diff --git a/.java.policy b/.java.policy
new file mode 100644
index 0000000..68a8e72
--- /dev/null
+++ b/.java.policy
@@ -0,0 +1,4 @@
+grant {
+permission java.sql.SQLPermission "callAbort";
+permission java.sql.SQLPermission "setNetworkTimeout";
+};
diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 0000000..e2a50e0
--- /dev/null
+++ b/.mvn/jvm.config
@@ -0,0 +1 @@
+--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..fd38483
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,115 @@
+os: linux
+dist: bionic
+language: java
+services:
+  - docker
+  - mysql
+jdk: openjdk11
+addons:
+  hosts:
+    - mariadb.example.com
+    - mariadb1.example.com
+    - mariadb2.example.com
+    - mariadb3.example.com
+
+before_install:
+  - git clone https://github.com/mariadb-corporation/connector-test-machine.git
+  # Load cached docker images
+  - if [[ -d $HOME/docker ]]; then ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load"; fi
+
+cache:
+  directories:
+    - $HOME/docker
+    - $HOME/.m2
+
+env: local=0 RUN_LONG_TEST=true
+
+install:
+  - |-
+    case $TRAVIS_OS_NAME in
+      windows)
+        choco install openjdk11 maven
+        export PATH=$(cmd.exe //c "refreshenv > nul & C:\Progra~1\Git\bin\bash -c 'echo \$PATH' ")
+        connector-test-machine/launch.bat -t "$srv" -v "$v" -d testj
+        ;;
+      linux)
+        source connector-test-machine/launch.sh -t "$srv" -v "$v" -d testj -l "$local" -p "$packet"
+        ;;
+    esac
+
+stages:
+  - Minimal
+  - name: Enterprise
+    if: type = push AND fork = false
+  - Community
+
+jobs:
+  allow_failures:
+    - env: srv=build
+    - env: srv=xpand TEST_DB_OTHER="&initSql=SET NAMES UTF8"
+  include:
+    - stage: Minimal
+      env: srv=mariadb v=10.6 packet=8
+      name: "CS 10.6"
+    - env: srv=mariadb-es v=10.6
+      name: "ES 10.6"
+      if: type = push AND fork = false
+
+    - stage: Enterprise
+      env: srv=mariadb-es v=10.4
+      name: "ES 10.4"
+    - env: srv=mariadb-es v=10.5
+      name: "ES 10.5"
+    - env: srv=maxscale
+      name: "Maxscale"
+    - env: srv=xpand TEST_DB_OTHER="&initSql=SET NAMES UTF8"
+      name: "Xpand"
+    - env: srv=skysql
+      name: "SkySQL"
+    - env: srv=skysql-ha
+      name: "SkySQL with replication"
+
+    - stage: Community
+      env: srv=mariadb v=10.6
+      os: windows
+      language: shell
+      name: "CS 10.6 - Windows"
+    - env: srv=mariadb v=10.3 local=1
+      name: "CS 10.3"
+    - env: srv=mariadb v=10.4 local=1
+      name: "CS 10.4"
+    - env: srv=mariadb v=10.5 local=1
+      name: "CS 10.5"
+    - env: srv=mariadb v=10.7 local=1
+      name: "CS 10.7"
+    - env: srv=mariadb v=10.8 local=1
+      name: "CS 10.8"
+    - env: srv=mariadb v=10.9 local=1
+      name: "CS 10.9"
+    - env: srv=mariadb v=10.6 packet=40
+      jdk: openjdk17
+      name: "CS 10.6 - openjdk 17"
+    - env: srv=mariadb v=10.6 packet=8
+      name: "CS 10.6 - packet 8M"
+    - env: srv=mariadb v=10.6 local=1 BENCH=1
+      name: "Benchmarks"
+    - env: srv=galera v=10.8
+      name: "Galera 10.8"
+    - env: srv=mysql v=5.7
+      name: "MySQL 5.7"
+    - env: srv=mysql v=8.0
+      name: "MySQL 8.0"
+    - env: srv=build
+      name: "CS build"
+
+script:
+  - mvn clean -Dmaven.test.skip
+  - if [ -n "$BENCH" ] ; then mvn package -P bench -Dmaven.test.skip -Dmaven.javadoc.skip=true ; fi
+  - if [ -n "$BENCH" ] ; then java -Duser.country=US -Duser.language=en -DTEST_PORT=$TEST_DB_PORT -DTEST_HOST=$TEST_DB_HOST -DTEST_USERNAME=$TEST_DB_USER -DTEST_PASSWORD=$TEST_DB_PASSWORD -jar target/benchmarks.jar; fi
+  - if [ -z "$BENCH" ] ; then MAVEN_SKIP_RC=true MAVEN_OPTS="-Xmx2g" mvn clean test -DjobId=${TRAVIS_JOB_ID}; fi
+
+after_script:
+  - bash <(curl -s https://codecov.io/bash)
+
+after_failure:
+  - if [ "$srv" == "maxscale" ] ; then docker-compose -f ${COMPOSE_FILE} exec -u root maxscale tail -500 /var/log/maxscale/maxscale.log; fi
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..5e65f42
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,1184 @@
+# Change Log
+
+## [3.1.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.1.2) (Jan 2023)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.1.1...3.1.2)
+
+* CONJ-1040 possible ConcurrentModificationException when connecting
+* CONJ-1041 possible ArrayIndexOutOfBoundsException
+
+## [2.7.8](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.8) (Jan 2023)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.7...2.7.8)
+
+* CONJ-1039 setQueryTimeout not honored by CallableStatement for procedures depending on security context
+* CONJ-1041 possible ArrayIndexOutOfBoundsException
+* CONJ-1023 set missing SSL capability in handshake after SSL exchanges
+
+
+## [3.1.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.1.1) (Jan 2023)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.1.0...3.1.1)
+
+- 3.0.10 bug fix:
+  - CONJ-1023	Connector/J doesn't set SSL cap bit in Handshake Response Packet
+  - CONJ-1026	timezone=auto option failure on non-fixed-offset zone machine
+  - CONJ-1032	Compatibility for deprecated arguments is case sensitive now
+- CONJ-1036	org.mariadb.jdbc.client.socket.impl.PacketWriter.writeAscii() broken in 3.1.0
+
+
+## [3.0.10](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.10) (Jan 2023)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.9...3.0.10)
+
+* CONJ-1023	Connector/J doesn't set SSL cap bit in Handshake Response Packet
+* CONJ-1026	timezone=auto option failure on non-fixed-offset zone machine
+* CONJ-1032	Compatibility for deprecated arguments is case sensitive now
+
+## [3.1.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.1.0) (Nov 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.9...3.1.0)
+
+##### Notable Changes
+* CONJ-899 Support UUID Object
+* CONJ-916 when a failover occurs, log replayed transaction
+* CONJ-917 deprecated options use must be logged
+* CONJ-992 load balance distribution
+* CONJ-1008	default value for socket option useReadAheadInput
+* CONJ-1009	improve performance reading big result-set
+* CONJ-1014	avoid creating array when receiving server packet
+* CONJ-1015	pipelining sending multiple packet to socket
+
+##### Bugs Fixed
+* CONJ-1020	java 11 option setting ignored
+
+## [3.0.9](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.9) (Nov 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.8...3.0.9)
+* 2.7.7 merge
+* CONJ-1012	stored procedure register output parameter as null if set before registerOutParameter command
+* CONJ-1017 Calendar possible race condition, cause wrong timestamp setting
+
+## [2.7.7](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.7) (Nov 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.6...2.7.7)
+
+* CONJ-1021 GSSAPI authentication might result in connection reset
+* CONJ-1019 DatabaseMetaData.getImportedKeys should return real value for PK_NAME column
+* CONJ-1016 avoid splitting BULK command into multiple commands in case of prepareStatement.setNull() use
+* CONJ-1011 correcting possible NPE when using statement.cancel() that coincide with statement.close() in another thread
+* CONJ-1007 Socket file descriptors are leaked after connecting with unix socket if DB is not up running
+
+## [3.0.8](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.8) (Sept 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.7...3.0.8)
+
+##### Notable Changes
+* small performance improvement
+  * [CONJ-1010] improve client side prepared parameter parameter substitution
+  
+##### Bugs Fixed
+* [CONJ-997] regression in 3.x when using option galeraAllowedState resulting in an IndexOutOfBoundsException
+* [CONJ-1002] 2nd failover reconnection ignores default database/schema setting when not set by connection string
+* [CONJ-1003] replication configuration always use 1st replica on 3.0
+* [CONJ-996] BatchUpdateException doesn't inherited the SQLState & vendorCode from the cause SQL exception
+* [CONJ-1006] disabling cachePrepStmts with useServerPrepStmts might result in Exception
+* [CONJ-1007] Socket file descriptors are leaked after connecting with unix socket if DB is not up running
+* [CONJ-1010] improve client side prepare statement parameter substitution
+* [CONJ-999] setting createDatabaseIfNotExist option use on read-only server will refuse connection on 3.0
+
+
+## [3.0.7](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.7) (Jul 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.6...3.0.7)
+
+* [CONJ-993] SQLDataException reading DATA_TYPE on DatabaseMetaData.getTypeInfo() after 3.0.4		
+* [CONJ-986] Permit specific Statement.setLocalInfileInputStream for compatibility 
+* [CONJ-987] Version 3.0.0 returns String for VARBINARY instead of byte[] as 2.7.6 did		
+* [CONJ-989] Binary column read as String
+* [CONJ-990] Setting timezone=UTC result in SQLSyntaxErrorException		
+* [CONJ-991] Regression: binary(16) is returned as String by getObject()		
+* [CONJ-994] Version 3.x rejects previously accepted boolean string parameter for BOOLEAN field
+
+## [3.0.6](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.6) (Jun 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.5...3.0.6)
+
+* [CONJ-953] PreparedStatement.getGeneratedKeys() returns rows when no keys are generated in insert
+* [CONJ-975] ArrayIndexOutOfBoundsException when attempt to getTime() from ResultSet
+* [CONJ-976] Improve use of pipelining when allowLocalInfile is enabled
+* [CONJ-979] ResultSet.getObject() returns Byte instead of Boolean for tinyint(1)
+* [CONJ-980] Permit setObject with java.util.Date parameter
+* [CONJ-984] Permit executing initial command with new option `initSql`
+* [CONJ-985] ResultSet.getObject() returns ByteSet instead of Byte[] for BIT
+
+## [3.0.5](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.5) (may 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.4...3.0.5)
+
+* [CONJ-956] ArrayIndexOutOfBoundsException when alias length > 250		
+* [CONJ-947] value after milliseconds precision lost when timestamp is encoded		
+* [CONJ-949] keep clientCertificateKeyStoreUrl and clientCertificateKeyStoreUrl aliases
+* [CONJ-950] metadata TEXT/TINYTEXT/MEDIUMTEXT/LONGTEXT wrong column type and length
+* [CONJ-954] java.time.OffsetDateTime not supported
+* [CONJ-958] compatibility with 2.7: now loop through hosts when multiple host without failover mode	
+* [CONJ-959] java.time.Instant not supported		
+* [CONJ-961] LOAD DATA LOCAL INFILE was disable by default		
+* [CONJ-962] resultset for negative TIME value return erronous LocalDateTime values		
+* [CONJ-965] better error message when not loading serverSslCert file
+* [CONJ-967] clearParameters() breaks validity when using output parameters in stored procedures		
+* [CONJ-969] org.mariadb.jdbc.ClientPreparedStatement is missing a toString implementation, useful for logging
+
+
+## [3.0.4](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.4) (Mar 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.3...3.0.4)
+
+* [CONJ-915] javadoc addition
+* [CONJ-921] DatabaseMetadata#getTables with null value for tableNamePattern throws Syntax error
+* [CONJ-922] DECIMAL overflow for long/int/short not throwing exception
+* [CONJ-924] NULL column type might result in java.lang.IllegalArgumentException: Unexpected datatype NULL
+* [CONJ-926] Client restrict authentication to 'mysql_native_password,client_ed25519,auth_gssapi_client' if restrictedAuth parameter is not set
+* [CONJ-924] NULL column test correction
+* [CONJ-923] correctly return 64 bits generated id / updated rows
+* [CONJ-933] load-balancing failover doesn't timeout
+* [CONJ-935] Connection.getMetaData() returns MariaDbClob instead of String
+* [CONJ-937] metadata getColumnTypeName wrong return type
+* [CONJ-934] MariaDbDataSource is sensitive to the order of setting of username and password
+* [CONJ-932] Login packet now use recommended length encoded value for connection attributes
+* [CONJ-925] missing OSGI infos
+* [CONJ-945] ensure retry is limited by retriesAllDown
+* [CONJ-940] Permit updating rows when not having primary info on metadata (Xpand)
+* [CONJ-939] add Xpand testing
+
+
+## [3.0.3](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.3) (Jan 2022)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.2-rc...3.0.3)
+
+* [CONJ-908] correct Connection.prepareStatement(String sql, int[] columnIndexes/String[] columnNames) to return generated keys
+* [CONJ-909] adding createDatabaseIfNotExist option for 2.x compatibility
+* [CONJ-910] permit jdbc:mysql scheme when connection string contains "permitMysqlScheme" for compatibility
+* [CONJ-913] Avoid executing additional command on connection for faster connection creation
+* [CONJ-912] remove security manager code (JEP 411)
+* [CONJ-911] enable keep-alive by default
+* failover improvement. some specific commands not in transaction are considered to be replayed in case of failover, like PING, PREPARE, ROLLBACK, ...
+* CONJ-705 parameter metadata get parameter count even when query cannot be prepared
+* prepareStatement.addBatch must initialize with previous set
+* Connection.prepareStatement(String sql, int[] columnIndexes/String[] columnNames) must return generated keys
+* setting "transaction read only" only for replica
+* keeping option interactiveClient for compatibility
+* adding option `transactionReplaySize` to control redo cache size
+* only set skip metadata connection flag when using binary protocol
+* permit getString on a binary object
+* compression correction for multi-packet
+* COM_RESET_CONNECTION expect a response (ERR_Packet or OK_Packet)
+* [CONJ-901] ArrayIndexOutOfBoundsException on StandardReadableByteBuf.readByte error
+
+## [3.0.2-rc](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.2-rc) (31 Aug 2021)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.1-beta...3.0.2-rc)
+
+* CONJ-879 Java 9 module full support
+  *  Aws IAM credential now use sdk v2 authentication that support java 9 modularity 
+* CONJ-896 Ensure pool connections validation when a socket fail
+* CONJ-897 Ensure having connection's thread id in Exception / debug logs
+
+minor: 
+* Ensure travis testing for PR/fork 
+
+## [3.0.1-beta](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.1-beta) (29 Jul 2021)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.0.0-alpha...3.0.1-beta)
+
+* CONJ-879 Provide JPMS module descriptor
+* CONJ-880 metadata query performance correction
+* CONJ-884 MariaDbPoolDataSource leaks connections when the mariadb server restarts
+* CONJ-885 org.mariadb.jdbc.internal.util.pool.Pool swallows SQLException during addConnection
+* CONJ-891 getImportedKeys with null catalog restrict result to current database		
+* CONJ-894 Adding useMysqlMetadata for 2.7 compatibility
+
+
+## [2.7.4](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.4) (29 Jul 2021)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.3...2.7.4)
+
+* CONJ-890	getImportedKeys/getTables regression returning an empty resultset for null/empty catalog
+* CONJ-863	Ensure socket state when SocketTimeout occurs
+* CONJ-873	IndexOutOfBoundsException when executing prepared queries using automatic key generation in parallel
+* CONJ-884	MariaDbPoolDataSource leaks connections when the mariadb server restarts
+* CONJ-893	DatabaseMetaData.getColumns regression causing TINYINT(x) with x > 1 to return BIT type in place of TINYINT
+* CONJ-889	CallableStatement using function throw wrong error on getter
+
+
+## [3.0.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.0.0) (3 May 2021)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.2...3.0.0)
+
+This version is a total rewrite of java driver. 
+
+* complete rewrite, code clarification, reduced size (15%), more than 90% coverage tested.
+* Encoding/decoding implementation are now registred by Codec, permitting codec registry implementation
+  * example support of Geometry Object 
+* Permit authentication plugin restriction by option `restrictedAuth`
+* performance improvement:
+  * Prepare and execution are now using pipelining when using option `useServerPrepStmts`
+  * performance enhancement with MariaDB 10.6 server when using option `useServerPrepStmts`, skipping metadata (see https://jira.mariadb.org/browse/MDEV-19237)
+
+
+correction: 
+* CONJ-864 includeThreadDumpInDeadlockExceptions always includes the thread dump, even when it is not a deadlock exception
+* CONJ-858 Properties parameter that differ from string not taken in account
+
+### Easy logging
+If using slf4J, just enabled package "org.mariadb.jdbc" log.
+
+level ERROR will log connection error
+level WARNING will log query errors
+level DEBUG will log queries
+level TRACE will log all exchanges with server.
+
+If not using slf4J, console will be used. 
+If really wanting to use JDK logger, System property "mariadb.logging.fallback" set to JDK will indicate to use common logging. 
+
+
+### Failover
+Failover implementation now permit redoing transaction : 
+when creating a transaction, all command will be cached, and can be replayed in case of failover. 
+
+This functionality can be enabled using option `transactionReplay`.
+
+This is not enabled by default, because this required that application to avoid using non-idempotent commands. 
+
+example:
+```sql
+START TRANSACTION;
+select next_val(hibernate_sequence);
+INSERT INTO myCar(id, name) VALUE (?, ?) //with parameters: 1, 'car1'
+INSERT INTO myCarDetail(id, carId, name) VALUE (?, ?, ?) //with parameters: 2, 1, 'detail1'
+INSERT INTO myCarDetail(id, carId, name) VALUE (?, ?, ?) //with parameters: 3, 2, 'detail2'
+COMMIT;
+```
+
+### Allow setup of TCP_KEEPIDLE, TCP_KEEPCOUNT, TCP_KEEPINTERVAL
+
+Equivalent options are `tcpKeepIdle`, `tcpKeepCount`, `tcpKeepInterval`
+Since available only with java 11, setting this option with java < 11 will have no effect. 
+
+## [2.7.3](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.3) (12 May 2021)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.2...2.7.3)
+
+* CONJ-619	Multiple batch update fails after LOAD DATA LOCAL INFILE
+* CONJ-854	LOAD XML INFILE breaks when using LOCAL
+* CONJ-855	throwing more specific exception for updatable result-set that can not be updated by ResultSet
+* CONJ-857	Remove use of mysql.proc table, relying on information_schema.parameters
+* CONJ-864	includeThreadDumpInDeadlockExceptions always includes the thread dump, even when it is not a deadlock exception
+* CONJ-866	long binary parsing improvement
+* CONJ-871	OSGi: Missing Import-Package in Connector/J bundle (javax.sql.rowset.serial)
+* CONJ-878	option serverSslCert file location
+* CONJ-880	metadata query performance correction
+* CONJ-858	Properties.put with object that differ from String supported even if use is not recommended
+* CONJ-861	executeBatch must not clear last parameter value.
+* CONJ-883	using unix socket, hostname is not mandatory anymore
+
+
+## [2.7.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.2) (29 Jan. 2021)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.1...2.7.2)
+
+* CONJ-847 NPE at UpdatableResultSet#close
+* CONJ-849 driver now doesn't close connection caused java.io.NotSerializableException as a result of incorrect data bind to a prepared statement parameter
+* CONJ-850 MariaDbResultSetMetaData#getPrecision(int) now returns correct length for character data
+* CONJ-851 metadata getBestRowIdentifier incompatibility with MySQL 8 correction
+* CONJ-853 Support Aurora cluster custom endpoints
+* CONJ-852 ON DUPLICATE KEY detection failed when using new line
+
+
+## [2.7.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.1) (23 Nov. 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.0...2.7.1)
+
+* CONJ-834 use of BULK batch is conditioned by capability, not checking server version
+* CONJ-835 GSS Imports set in OSGI Bundle
+* CONJ-839 Wrong exception message when rewriteBatchedStatements is enabled
+* CONJ-841 ResultSetMetaData::getColumnTypeName() returns incorrect type name for LONGTEXT
+* CONJ-842 Byte array parameters are now send as long data
+* CONJ-837 prepared statement cache leak on ResultSet CONCUR_UPDATABLE concurrency
+* CONJ-843 ParameterMetaData::getParameterType for CallableStatement parameter return expected "BINARY" value for BINARY type
+
+minor:
+* CONJ-845 test suite now test SkySQL with replication setting
+* CONJ-838 have a 'replica' alias for 'slave' connection option
+
+
+## [2.7.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.0) (24 Sep. 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.6.2...2.7.0)
+
+* CONJ-805	maxFieldSize string truncation occurs on bytes' length, not character length
+* CONJ-807	Correcting possible Get Access Denied error if using multiple classloader
+* CONJ-810	normalization of resultset getDate/getTime of timestamp field.
+* CONJ-812	DatabaseMetadata.getBestRowIdentifier and getMaxProcedureNameLength correction
+* CONJ-813	setConfiguration not being called on classes that extend ConfigurableSocketFactory
+* CONJ-816	Table with primary key with DEFAULT function can be inserted for 10.5 servers
+* CONJ-817	Switched position of REMARKS and PROCEDURE_TYPE in the getProcedures result
+* CONJ-820	MySQLPreparedStatement.setObject can now handle java.lang.Character type
+* CONJ-828	new option `ensureSocketState` to ensure protocol state
+* CONJ-829	Option to cache callablestatement is now disabled by default
+* CONJ-830	connector now throw a better error if SSL is mandatory and server doesn't support SSL
+* CONJ-814	Small possible improvement of getCrossReference, getExportedKeys and getImportedKey
+* CONJ-825	XAResource.isSameRM implementation
+
+## [2.6.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.6.2) (23 Jul. 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.6.1...2.6.2)
+
+* CONJ-804 - Automatic charset correction
+* CONJ-809 - SelectResultSet's (ResultSet)MetaData always indicates all columns to be readonly
+* CONJ-802 - Version parsing depending on Classloader might result in connection Exception
+
+
+## [2.6.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.6.1) (23 Jun. 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.6.0...2.6.1)
+
+* CONJ-781 - DatabaseMetaData.supportsMultipleResultSets() now return correctly true.
+* CONJ-791 - Using CallableStatement.getTimestamp() can't get data correctly
+* CONJ-705 - ParameterMetadata now return parameterCount() even if no information
+* CONJ-775 - avoid a NPE for malformed "jdbc:mariadb:///" connection string.
+* CONJ-776 - Temporal Data Tables are not listed in metadata
+* CONJ-785 - corrected escape sequence for multiple backslash escape
+* CONJ-786 - Connection.setReadOnly(true ) with option `assureReadOnly` now force read only connection even for mono server*
+* CONJ-795 - permit resultset.getRow() for TYPE_FORWARD_ONLY when streaming
+* CONJ-797 - Connector set UTF8mb4 equivalent in case of server configured with UTF8mb3 collation
+* CONJ-800 - implement Statement setEscapeProcessing to avoid escape
+* CONJ-801 - possible race condition using resultset getter using label
+* CONJ-778 - Missing import org.osgi.service.jdbc in Import-Package clause of the OSGi manifest
+* CONJ-779 - Logic error in stop() method of OSGi bundle activator
+* CONJ-780 - Logic error in implementation of OSGi DataSourceFactory (MariaDbDataSourceFactory)
+* CONJ-788 - resultset metadata always indicate that column is writable even if not
+* CONJ-789 - ensure connection reference removal on (prepared)Statement close
+* CONJ-782 - SkySQL testing
+
+## [2.6.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.6.0) (19 Mar. 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.5.4...2.6.0)
+
+* CONJ-768 - Check Galera allowed state when connecting when option `galeraAllowedState` is set, and not only on validation
+* CONJ-759 - on failover, catalog changed might not be set when automatically recreating a connection.
+* CONJ-761 - remove unnecessary dependencies for fedora tar creation
+* CONJ-763 - Custom SocketFactory now can change options
+* CONJ-764 - DatabaseMetaData.getExportedKeys should return "PRIMARY" for PK_NAME column
+* CONJ-765 - Allow MariaDbDatabaseMetaData#getExportedKeys to return the exported keys for all tables
+* CONJ-766 - Adding a socket timeout until complete authentication, to avoid hangs is server doesn't support pipelining
+* CONJ-767 - permit using Aurora RO endpoint
+* CONJ-771 - enablePacketDebug must not reset stack on failover
+* CONJ-772 - JDBC Conversion Function support parsing correction
+
+## [2.5.4](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.5.4) (27 Jan. 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.5.3...2.5.4)
+
+* CONJ-756 - Logging correction when using enablePacketDebug option
+* CONJ-755 - permits avoiding setting session_track_schema with new option `trackSchema`
+
+## [2.5.3](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.5.3) (07 Jan. 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.5.2...2.5.3)
+
+* CONJ-752 - Manifest file wrong entry - thanks to Christoph Läubrich
+* CONJ-750 - protocol error when not setting database with maxscale
+* CONJ-747 - JDBC Conversion Function fast-path skipped, always using longer implementation
+
+## [2.5.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.5.2) (22 Nov. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.5.1...2.5.2)
+
+* CONJ-745 - use pool reset only for corrected COM_RESET_CONNECTION
+* CONJ-743 - byte signed value wrong serialization for text protocol
+* CONJ-742 - ensure plugin using Driver classloader
+
+
+## [2.5.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.5.1) (15 Oct. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.5.0...2.5.1)
+
+* CONJ-736 - OSGI compliance
+* CONJ-737 - Error packet caching_sha2_password not handled when not having a password
+* CONJ-738 - PAM authentication multiple exchanges permitting multiple step in connection string
+* CONJ-735 - Multi insert regression correction returning multi generated keys
+
+
+## [2.5.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.5.0) (02 Oct. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.4.4...2.5.0)
+
+* CONJ-663 - Client authentication plugins are now defined as services. The driver has 2 new plugins `caching_sha2_password` and `sha256_password plugin` for MySQL compatibility
+* CONJ-733 - Credential service: AWS IAM authentication
+* CONJ-727 - Support configuration of custom SSLSocketFactory
+* CONJ-561 - JDBC 4.3 partial implementation java.sql.Statement methods isSimpleIdentifier, enquoteIdentifier, enquoteLiteral and enquoteNCharLiteral
+* CONJ-692 - ConnectionPoolDataSource interface addition to MariaDbPoolDataSource
+* CONJ-563 - closing possible option batch thread on driver registration.
+* CONJ-732 - Driver getPropertyInfo returns no options' information when url is empty
+* CONJ-734 - DatabaseMetaData.getSchemaTerm now return "schema", not empty string
+
+## [2.4.4](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.4.4) (14 Sep. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.4.3...2.4.4)
+
+* CONJ-724 - Do not ignore the Calendar parameter in ResultSet#getTime(int, Calendar)
+* CONJ-725 - Connection Failure when using PAM authenticated user on 10.4 MariaDB server
+* CONJ-729 - master-slave regression: commit on read-only server Executed only when there is an active transaction on master connection
+* CONJ-726 - removing possible NPE after failover on aurora cluster
+
+## [2.4.3](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.4.3) (02 Jul. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.4.2...2.4.3)
+
+* CONJ-717 - conversion function support for other data type than default MariaDB conversion type
+* CONJ-722 - Permit suppression of result-set metadata getTableName for oracle compatibility
+* CONJ-719 - Saving values using Java 8 LocalTime does not store fractional parts of seconds
+* CONJ-716 - Correcting possible NPE on non thread safe NumberFormat (logging)
+
+## [2.4.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.4.2) (17 Jun. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.4.1...2.4.2)
+
+Security
+* CONJ-679 - parse Query when receiving LOAD LOCAL INFILE
+
+Bugs
+* CONJ-703 - ClassNotFoundException when trying to connect using two-authentication in an OSGI environment.
+* CONJ-711 - Xid format id is unsigned integer, currently sending as signed value.
+* CONJ-700 - autoReconnect=true on Basic Failover doesn't reconnect
+* CONJ-707 - failover might throw an unexpected exception with using "failover"/"sequential" configuration on socket error
+* CONJ-709 - includeThreadDumpInDeadlockExceptions is thrown only if option includeInnodbStatusInDeadlockExceptions is set
+* CONJ-710 - Throw complete stackTrace when having an exception on XA Commands
+* CONJ-714 - Error on connection on galera server when in detached mode.
+* CONJ-701 - typo in error message in SelectResultSet.java
+
+## [2.4.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.4.1) (15 Mar. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.4.0...2.4.1)
+
+Evolutions
+* misc - enabled running of 'SHOW ENGINE INNODB STATUS' for error code 1213 (@mtykhenko)
+* misc - reduce mutex using select @@innodb_read_only for aurora (@matsuzayaws)
+
+Bugs
+* misc - updating checkstyle version dependency
+* misc - permit using SSL on localsocket
+* CONJ-687 - addition of option "useMysqlMetadata" to permit MySQL meta compatibility
+* misc - java PID using java 9 ProcessHandle if existing, relying on JNA if present
+* CONJ-682 - internal pool correction: when receiving an RST during connection validation, the pool will end up throwing connection timeout exception in place of reusing another connection.
+
+## [2.4.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.4.0) (28 Jan. 2019)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.3.0...2.4.0)
+
+Evolutions
+* CONJ-675 - permit multiple alternative authentication methods for the same user (future MariaDB 10.4 feature)
+* CONJ-678 - permit indication of truststore/keystore type (JKS/PKCS12), then not relying on java default type
+* CONJ-378 - GSSAPI: client can provide SPN
+* CONJ-667 - Support MYSQL_TYPE_JSON datatype
+* CONJ-652 - faster results buffering socket available
+* CONJ-659 - improve text performance reading date/time/timestamp resultset
+* CONJ-670 - ability to Refresh SSL certificate
+
+New options
+
+|Option|Description|
+|---|---|
+|useReadAheadInput|use a buffered inputSteam that read socket available data. <br /><i>Default: true</i>|
+|keyStoreType|indicate key store type (JKS/PKCS12). default is null, then using java default type.|
+|trustStoreType|indicate trust store type (JKS/PKCS12). default is null, then using java default type|
+|servicePrincipalName|when using GSSAPI authentication, SPN (Service Principal Name) use the server SPN information. When set, connector will use this value, ignoring server information|
+
+Bugs
+* CONJ-646 - possible NullPointerException when connection lost to database using aurora configuration with one node
+* CONJ-672 - batch using multi-send can hang when using query timeout
+* CONJ-544 - disable SSL session resumption when using SSL
+* CONJ-589 - correcting Clob.length() for utf8mb4
+* CONJ-649 - datasource connectTimeout URL parameter is not honoured
+* CONJ-650 - Correction on resultset.getObject(columnName, byte[].class) when value is NULL
+* CONJ-665 - old MySQL (<5.5.3) doesn't support utf8mb4, using utf8 on 3 bytes as connection charset by default
+* CONJ-671 - MariaDb bulk threads occupy full cpu(99%) while db connections broken
+* CONJ-673 - abording a connection while fetching a query still does read whole resultset
+* CONJ-669 - SQLSyntaxErrorException when querying on empty column name
+* CONJ-674 - make dumpQueriesOnException = false by default as per documentation
+
+minor:
+* CONJ-644 - small optimization when validating galera connection
+* CONJ-625 - add coverage test
+* CONJ-654 - DatabaseMetaData.getDriverName() returns connector/J with a lowercase c
+
+
+## [2.3.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.3.0) (06 Sep. 2018)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.2.6...2.3.0)
+
+#### [CONJ-398] Improve deadlock debugging capabilities
+
+MariaDB has now 2 new options to permit identifying deadlock :
+New options
+
+|Option|Description|
+|---|---|
+|includeInnodbStatusInDeadlockExceptions|add "SHOW ENGINE INNODB STATUS" result to exception trace when having a deadlock exception.<br /><i>//Default: false</i>|
+|includeThreadDumpInDeadlockExceptions|add thread dump to exception trace when having a deadlock exception.<br /><i>Default: false</i>|
+
+#### [CONJ-639] the option "enabledSslProtocolSuites" now include TLSv1.2 by default
+previous default value was "TLSv1, TLSv1.1", disabling TLSv1.2 by default, due to a corrected issue (MDEV-12190) with servers using YaSSL - not openSSL. Server error was .
+Now, the default value is "TLSv1, TLSv1.1, TLSv1.2". So TLSv1.2 can be use directly.
+Connecting MySQL community server use YaSSL without correction, and connection might result in SSLException: "Unsupported record version Unknown-0.0".
+
+
+#### [CONJ-642] disable the option "useBulkStmts" by default
+Using useBulkStmts permit faster batch, but cause one major issue : Batch return -1 = SUCCESS_NO_INFO
+
+Different option use this information for optimistic update, and cannot confirm if update succeed or not.
+This option still makes sense, since for big batch is way faster, but will not be activated by default.
+
+
+##= Minor change:
+* CONJ-628 - optimization to read metadata faster
+* CONJ-637 - java.sql.Driver class implement DriverPropertyInfo[] getPropertyInfo, permitting listing options on querying tools
+* CONJ-639 - enabledSslProtocolSuites does not include TLSv1.2 by default
+* CONJ-641 - update maven test dependencies for java 10 compatibility
+* CONJ-643 - PreparedStatement::getParameterMetaData always returns VARSTRING as type resulting in downstream libraries interpreting values wrongly
+
+##= Bug correction:
+* CONJ-616 - correction on possible NPE on getConnection when using failover configuration and master is down, not throwing a proper exception
+* CONJ-636 - Error in batch might throw a NPE and not the proper Exception
+
+
+## [2.2.6](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.2.6) (19 Jul. 2018)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.2.5...2.2.6)
+
+minor change:
+* CONJ-623 - Increase connection logging when Primary node connection fails
+* CONJ-384 - Permit knowing affected rows number, not only real changed rows
+
+New options
+|=useAffectedRows|default correspond to the JDBC standard, reporting real affected rows. if
+enable, will report "affected" rows. example : if enabled, an update command that doesn't change a row value will still be "affected", then report.<br /><i>Default: false. Since 2.2.6</i>
+
+Bug correction:
+* CONJ-624 - MariaDbPoolDataSource possible NPE on configuration getter
+* CONJ-623 - Increase connection logging when Primary node connection fails
+* CONJ-622 - The option "connectTimeout" must take in account DriverManager.getLoginTimeout() when set
+* CONJ-621 - wrong escaping when having curly bracket in table/field name
+* CONJ-618 - Client preparestatement parsing error on escaped ' / " in query
+
+
+## [2.2.5](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.2.5) (28 May. 2018)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.2.4...2.2.5)
+
+minor change:
+* CONJ-602 - Add server hostname to connection packet for proxy
+* CONJ-604 - handle support for mysql 8.0 tx_isolation replacement by transaction_isolation
+
+Bug correction:
+* CONJ-613 - Connection using "replication" Parameters fail when no slave is available
+* CONJ-595 - Create option to configure DONOR/DESYNCED Galera nodes to be unavailable for load-balancing
+* CONJ-605 - Newlines where breaking calling stored procedures
+* CONJ-609 - Using getDate with function DATE_ADD() with parameter using string format where return wrong result using binary protocol
+* CONJ-610 - Option "allowMasterDownConnection" improvement on connection validation and Exceptions on master down
+
+## [2.2.4](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.2.4) (04 May. 2018)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.2.3...2.2.4)
+
+Minor changes:
+* CONJ-580 - Some options are missing in documentation like default 'autocommit' value
+* CONJ-597 - Internal exchanges send utf8mb4 with server even if default server collation is not utf8/utf8mb4
+* CONJ-600 - Upgrading non-mandatory Waffle dependency to 1.9.0 (windows GSSAPI authentication)
+* CONJ-575 - test addition to ensure YaSSL downgrade TLSv1.2 protocol to TLSv1.1
+
+## [2.2.3](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.2.3) (08 Mar. 2018)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.2.2...2.2.3)
+
+Bug correction:
+* CONJ-583 - possible hang indefinitely using master/slave configuration and failover occur
+* CONJ-586 - erroneous transaction state when first command result as error
+* CONJ-587 - using allowMasterDownConnection option can lead to NPE when using setReadOnly()
+* CONJ-588 - using option 'allowMasterDownConnection' won't permit connecting if master is down
+* CONJ-534 - Connection.isValid() must be routed to Master and Slave connections to avoid any server timeout
+
+## [2.2.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.2.2) (20 Feb. 2018)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.2.1...2.2.2)
+
+Bug correction:
+* CONJ-564 - Never ever throw an instance of java.lang.Error
+* CONJ-579 - Keywords missing from DatabaseMetaData.getSQLKeywords()
+* CONJ-567 - UrlParser.initialUrl gets overwritten
+* CONJ-571 - Permit java 9 serialization filtering
+* CONJ-574 - forcing using toLowerCase/toUpperCase with Locale.ROOT
+* CONJ-560 - Automatic module name for java 9
+* CONJ-578 - windows testing using all mariadb server
+* CONJ-570 - Add tests for 10.3.3 INVISIBLE column
+
+## [2.2.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.2.1) (22 Dec. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.2.0...2.2.1)
+
+* CONJ-501 - provide support for authentication plugin ed25519
+
+Bug correction:
+* CONJ-529 - failover : the driver will pause for 250ms if no servers are available before attempting to reconnect another time
+* CONJ-548 - don't use COM_STMT_BULK_EXECUTE for INSERT ... SELECT statements
+* CONJ-549 - correction on connection reset when using MariaDbPoolDataSource with options useServerPrepStmts and useResetConnection enabled
+* CONJ-555 - failover caused by client timeout must not reuse connection
+* CONJ-558 - removing extra ".0" to resultset.getString() value for FLOAT/DOUBLE fields
+* CONJ-550 - fetching state correction when reusing statement without having read all results
+* CONJ-553 - RejectedExecutionException was thrown when having large amount of concurrent batches
+
+
+
+## [2.2.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.2.0) (08 Nov. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.1.2...2.2.0)
+
+Evolutions:
+#### CONJ-522 - Pool datasource implementation
+
+MariaDB has now 2 different Datasource implementation :
+* MariaDbDataSource : Basic implementation. A new connection each time method getConnection() is called.
+* MariaDbPoolDataSource : Connection pooling implementation. MariaDB Driver will keep a pool of connection and borrow Connections when asked for it.
+
+New options
+
+|Option|Description|
+|---|---|
+|pool|Use pool. This option is useful only if not using a DataSource object, but only connection object. <br /><i>Default: false. since 2.2.0</i>|
+|poolName|Pool name that will permit to identify thread.<br />default: auto-generated as MariaDb-pool-<pool-index> <i>since 2.2.0</i>|
+|maxPoolSize| The maximum number of physical connections that the pool should contain. <br /><i>Default: 8. since 2.2.0</i>|
+|minPoolSize| When connection are removed since not used since more than "maxIdleTime", connections are closed and removed from pool. "minPoolSize" indicate the number of physical connections the pool should keep available at all times. Should be less or equal to maxPoolSize.<br /><i>Default: maxPoolSize value. Since 2.2.0</i>|
+|poolValidMinDelay| When asking a connection to pool, Pool will validate connection state. "poolValidMinDelay" permit to disable this validation if connection has been borrowed recently avoiding useless verification in case of frequent reuse of connection. 0 meaning validation is done each time connection is asked.<br /><i>Default: 1000 (in milliseconds). Since 2.2.0</i>|
+|maxIdleTime|The maximum amount of time in seconds that a connection can stay in pool when not used. This value must always be below @wait_timeout value - 45s <br /><i>Default: 600 in seconds (=10 minutes), minimum value is 60 seconds. Since 2.2.0</i>|
+|staticGlobal|Indicate the following global variable (@@max_allowed_packet,@@wait_timeout,@@autocommit,@@auto_increment_increment,@@time_zone,@@system_time_zone,@@tx_isolation) values won't changed, permitting to pool to create new connection faster.<br /><i>Default: false. Since 2.2.0</i>|
+|useResetConnection|When a connection is closed() (give back to pool), pool reset connection state. Setting this option, session variables change will be reset, and user variables will be destroyed when server permit it (MariaDB >= 10.2.4, MySQL >= 5.7.3), permitting to save memory on server if application make extensive use of variables<br /><i>Default: false. Since 2.2.0</i>|
+
+Other evolutions:
+* CONJ-530 - Permit Connection.abort() forcing killing the connection, even if connection is stuck in another thread
+* CONJ-531 - permit cancelling streaming result-set using Statement.cancel.
+* CONJ-495 - Improve reading result-set data
+* CONJ-510 - allow execution of read-only statements on slaves when master is down
+
+
+Bug :
+* CONJ-532 - correction Statement.getMoreResults() for multi-queries
+* CONJ-533 - PrepareStatement.setTime() may insert incorrect time according to current timezone, time and option "useLegacyDatetimeCode"
+* CONJ-535 - correction on numerical getter for big BIT data type fields
+* CONJ-541 - Fix behavior of ResultSet#relative when crossing result set boundaries
+
+
+Misc:
+* CONJ-469 - Improve Blob/Clob implementation (avoiding array copy from result-set row)
+* CONJ-539 - better message when server close connection
+* misc - resultset.findColumn method use column name if alias not found
+* misc - default option "connectTimeout" value to 30 seconds (was 0 = no timeout)
+* misc - ensure that enablePacketDebug option works when timer tick is big
+
+
+
+## [2.1.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.1.2) (24 Sep. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.1.1...2.1.2)
+
+Bug :
+* CONJ-525 - Batch result-set return array correction when DELETE statement when bulk option is used
+* CONJ-526 - better error message getting metadata information when SQL syntax is wrong
+* CONJ-527 - Resultset.last() return wrong value if resultset has only one result
+* CONJ-528 - Error executing LOAD DATA LOCAL INFILE when file is larger than max_allowed_packet
+
+
+## [2.1.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.1.1) (05 Sep. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.1.0...2.1.1)
+
+Bug :
+* CONJ-519 - Updatable result-set possible NPE when same field is repeated.
+* CONJ-514 - ResultSet method wasNull() always return true after a call on a "null-date" field binary protocol handling
+* CONJ-516 - Permit using updatable result-set when fetching
+* CONJ-511 - Add legacy SSL certificate Hostname verification with CN even when SAN are set
+* CONJ-515 - Improve MariaDB driver stability in case JNA errors
+
+misc :
+* correct typo in error message when setting wrong parameter
+* add trace to HostnameVerifier implementation
+* handling connection error when no database is provided
+
+
+## [2.1.0](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.1.0) (29 Jul. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.0.3...2.1.0)
+
+##= CONJ-422 : verification of SSL Certificate Name Mismatch
+When using ssl, driver check hostname against the server's identity as presented in the server's Certificate (checking alternative names or certificate CN) to prevent man-in-the-middle attack.
+
+A new option "disableSslHostnameVerification" permit to deactivate this validation.
+|=disableSslHostnameVerification| When using ssl, driver check hostname against the server's identity as presented in the server's Certificate (checking alternative names or certificate CN) to prevent man-in-the-middle attack. This option permit to deactivate this validation.<br />//Default: false. Since 2.1.0//
+
+##= CONJ-400 - Galera validation
+When configuration with multi-master, Connection.isValid() will not only validate connection, but primary state.
+A connection to a node that is not in primary mode will return false (then for pool, connection will be discarded)
+
+##= CONJ-322 - ResultSet.update* methods implementation
+ResultSet.update* methods aren't implemented
+statement using ResultSet.CONCUR_UPDATABLE must be able to update record.
+exemple:
+{{{
+Statement stmt = con.createStatement(
+ResultSet.TYPE_SCROLL_INSENSITIVE,
+ResultSet.CONCUR_UPDATABLE);
+ResultSet rs = stmt.executeQuery("SELECT age FROM TABLE2");
+// rs will be scrollable, will not show changes made by others,
+// and will be updatable
+while(rs.next()){
+//Retrieve by column name
+int newAge = rs.getInt(1) + 5;
+rs.updateDouble( 1 , newAge );
+rs.updateRow();
+}
+}}}
+
+
+##= CONJ-389 - faster batch insert
+Use dedicated [COM_STMT_BULK_EXECUTE |https://mariadb.com/kb/en/mariadb/com_stmt_bulk_execute/] protocol for batch insert when possible.
+(batch without Statement.RETURN_GENERATED_KEYS and streams) to have faster batch.
+(significant only if server MariaDB &ge; 10.2.7)
+
+A new option "useBulkStmts" permit to deactivate this functionality.
+|=useBulkStmts| Use dedicated COM_STMT_BULK_EXECUTE protocol for batch insert when possible. (batch without Statement.RETURN_GENERATED_KEYS and streams) to have faster batch. (significant only if server MariaDB &ge; 10.2.7)<br />//Default: true. Since 2.1.0//
+
+
+other evolution
+* CONJ-508 - Connection.getCatalog() optimisation for 10.2+ server using new session_track_schema capabilities
+* CONJ-492 - Failover handle automatic reconnection on KILL command
+
+Bug
+* CONJ-502 - isolation leak when using multiple pools on same VM on failover
+* CONJ-503 - regression on aurora Connection.isReadOnly()
+* CONJ-505 - correcting issue that ended throwing "Unknown prepared statement handler given to mysqld_stmt_execute"
+* CONJ-496 - return rounded numeric when querying on a decimal field in place of throwing an exception for compatibility
+
+
+## [2.0.3](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.0.3) (27 Jun. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.0.2...2.0.3)
+
+Bug
+* CONJ-473 - when useServerPrepStmts is not set, the PREPARE statement must not be cached.
+* CONJ-494 - Handle PrepareStatement.getParameterMetaData() if query cannot be PREPAREd
+* CONJ-497 - escape string correction for big query
+
+
+## [2.0.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.0.2) (05 Jun. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.0.1...2.0.2)
+
+Bug
+* CONJ-490 - DataSource connectTimeout is in second, but was set on socket timeout that is in milliseconds
+* CONJ-481 - Buffer overrun reading ResultSet when using option "useServerPrepStmts"
+* CONJ-470 - Error when executing SQL contains "values" and rewriteBatchedStatements=true
+* CONJ-471 - PK_NAME returned by DatabaseMetadata.getPrimaryKeys() should not be null
+* CONJ-477 - Aurora not compatible with option usePipelineAuth. Now automatically disabled when aurora is detected
+* CONJ-479 - ArrayIndexOutOfBoundsException on connect to MySQL 5.1.73
+* CONJ-480 - Access denied error on connect to MySQL 5.1.73
+* CONJ-483 - Wrong content of DEFERRABILITY column in MariaDbDatabaseMetaData
+* CONJ-487 - No timeout exception on Client PrepareStatement
+* CONJ-489 - javax.transaction.xa.XAException message error truncated ( near '0x )
+
+Task
+* CONJ-478 - Change CI tests to use maxscale 2.1 version
+* CONJ-482 - Connection.setNetworkTimeout don't throw exception if no executor
+* CONJ-488 - Use java.net.URL to read keyStore and trustStore again
+
+## [2.0.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.0.1) (10 May. 2017)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.0.0-RC...2.0.1)
+
+* CONJ-467 - changing database metadata to 4.2
+* CONJ-460 - Query that contain multiqueries with fetch and EOF deprecation failed
+* CONJ-464 - Using of "slowQueryThresholdNanos" option with value > Integer.MAX_VALUE results in class cast exception
+* CONJ-452 - correcting inline ssl server certificate parsing
+* CONJ-461 - LAST_INSERT_ID() validation check correction for rewrite statement
+* CONJ-465 - new option "enablePacketDebug"
+
+New Options :
+|=enablePacketDebug|Driver will save the last 16 MySQL packet exchanges (limited to first 1000 bytes).<br />Hexadecimal value of this packet will be added to stacktrace when an IOException occur.<br />This options has no performance incidence (< 1 microseconds per query) but driver will then take 16kb more memory.//Default: true. Since 1.6.0//|
+
+* CONJ-468 - autoIncrementIncrement value loaded during connection, avoiding a query for first statement for rewrite
+
+
+## [2.0.0-RC](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.0.0-RC) (20 Apr. 2017)
+
+Release candidate version.
+
+Java 8 is now minimum required version.
+
+##= CONJ-318 : Handle CLIENT_DEPRECATE_EOF flag
+Implement some protocol changes that permit to save some bytes.(part of https://jira.mariadb.org/browse/MDEV-8931).
+
+##= CONJ-341 : handle SERVER_SESSION_STATE_CHANGE status flag
+With server with version MariaDB 10.2, MySQL 5.7, ensure driver state :
+- driver does now always get current database, even database is changed by query.
+- when using rewriteBatchedStatements does return correct autoincrement ids even when session variable @auto_increment_increment has change during session.
+
+
+##= CONJ-393 : improve setQueryTimeout to use SET STATEMENT max_statement_time
+
+Previous implementation of query timeout handling (using Statement.setQueryTimeout) will create an additional thread with a scheduler.
+When timeout is reached, a temporary connection will be created to permit executing "KILL QUERY <current connection id>", then closing the temporary connection.
+When query ended before timeout, the scheduled task will be canceled.
+
+If server is > 10.1.2, query timeout will be handle server side using "SET MAX_STATEMENT_TIME FOR" command.
+
+##= [CONJ-315]
+
+Closing a Statement that was fetching a result-set (using Statement.setFetchSize) and all rows where not read at the time of closing, a kill query command
+will be executed on close, to avoid having to parse all remaining results.
+
+##= [CONJ-442]
+Memory optimization : streaming query.
+Very big command now doesn't use any intermediate buffer. Commands are sent directly to socket avoiding using memory, This permit to send very large object (1G) without using any additional memory.
+
+##= [CONJ-366]
+Faster connection : bundle first commands in authentication packet
+Driver execute different command on connection. Those queries are now send using pipeline (all queries are sent, then only all results are reads).
+
+New Options :
+|=usePipelineAuth|Fast connection creation.//Default: true. Since 2.0.0//|
+
+##= [CONJ-368]
+Parsing row result optimisation to avoid creating byte array to the maximum for faster results and less memory use.
+
+##= Remaining JDBC 4.2 missing implementation :
+- CONJ-414 - support for large update count [CONJ-414]
+- CONJ-409 - PrepareStatement.setObject(...) support for with java 8 temporal object.
+- CONJ-411 - support for Statement maxFieldSize
+
+##= Misc
+
+* CONJ-443 - NullpointerException when making concurrent procedure calls
+* CONJ-391 - Improve connection using SELECT in place of SHOW to avoid creating a mutex server side.
+* CONJ-402 - tcpKeepAlive option now default to true.
+* CONJ-448 - QueryException: Incorrect arguments to mysqld_stmt_execute on inserting an "emptyString"-Lob with JPA
+* CONJ-451 - Respect type parameter of ResultSet.getObject with type
+* CONJ-455 - MetaData : tinyInt1isBit doesn't work properly in TINYINT(1) column that is marked as UNSIGNED
+* CONJ-450 - NPE on setClientInfo if value is an empty string
+* CONJ-457 - trustStore : Retain leading slash when trust store beings with 'file:///'
+* CONJ-160 - ConnectionPool test using hikariCP
+* CONJ-307 - valid connector java 9 early access
+* CONJ-402 - make tcpKeepAlive option default to true
+* CONJ-411 - Implement Statement maxFieldSize
+* CONJ-449 - Permit CallableStatement streaming
+
+
+## 1.5.9
+* CONJ-212 : Implement password encoding charset option
+* CONJ-423 : Permit to have MySQL driver and MariaDB driver in same classpath
+* CONJ-431 : multi-values queries return only one generated key
+* CONJ-434 : 1.5.8 regression : ResultSet returns duplicate entries when using fetchsize
+* CONJ-437 : ResultSet.getString on field with ZEROFILL doesn't have the '0' leading chars when using binary protocol
+* CONJ-435 : avoid "All pipe instances are busy" exception on multiple connections to the same named pipe
+* CONJ-446 : ResultSet first() throw an exception for scroll type if TYPE_FORWARD_ONLY when streaming
+* CONJ-440 : handle very big COM_STMT_SEND_LONG_DATA packet (1Gb)
+* CONJ-429 : ResultSet.getDouble/getFloat may throw a NumberFormatException
+* CONJ-438 : using option rewriteBatchedStatements, permit rewrite when query has column/table that contain 'select' keyword.
+
+## 1.5.8
+* CONJ-424 : getGeneratedKeys() on table without generated key failed on second execution
+* CONJ-412 : Metadata take in account tinyInt1isBit in method columnTypeClause
+* CONJ-418 : ResultSet.last() isLast() afterLast() and isAfterLast() correction when streaming
+* CONJ-415 : ResultSet.absolute() should not always return true
+* CONJ-392 : Aurora cluster endpoint detection fails when time_zone doesn't match system_time_zone
+* CONJ-425 : CallableStatement getObject class according to java.sql.Types value
+* CONJ-426 : Allow executeBatch to be interrupted
+* CONJ-420 : High CPU usage against Aurora after 2 hours inactivity
+
+## 1.5.7
+* CONJ-407 : handling failover when packet > max_allowed_packet reset the connection state.
+* CONJ-403 : possible NPE on ResultSet.close() correction
+* CONJ-405 : Calendar instance not cleared before being used in ResultSet.getTimestamp
+
+
+## 1.5.6
+* CONJ-399 : resultSet getLong() for BIGINT column fails if value is Long.MIN_VALUE in Text protocol
+* CONJ-395 : Aurora does not randomise selection of read replicas
+* CONJ-392 : Aurora cluster endpoint detection timezone issue
+* CONJ-394 : mysql_native_password plugin authentication fail when default-auth set
+* CONJ-388 : handle timestamp '0000-00-00 00:00:00' getString()
+* CONJ-380 : add maxscale in CI
+* CONJ-391 : Use SELECT in place of SHOW command on connection
+* CONJ-396 : handling multiple resultSet correctly (was failing if more than 2)
+
+## 1.5.5
+* CONJ-386 : Disabling useBatchMultiSend option for Aurora, since can hang connection.
+* CONJ-385 : Store procedure with resultSet get wrong getUpdateCount() value (0 in place of -1)
+* CONJ-383 : permit OldAuthSwitchRequest protocol (compatibility with 5.5 server using plugin)
+* CONJ-382 : Client sockets remain option when server close socket when maximum connections number has been reached
+* CONJ-381 : Metadata getProcedureColumns precision's information corrected for date/timestamp/datetime
+* CONJ-379 : Metadata TINYTEXT type return Types.LONGVARCHAR instead of Types.VARCHAR
+* CONJ-376 : Maxscale compatibility : Permit protocol compression only if server permit it
+* CONJ-375 : Load data infile with large files fails with OutOfMemoryError
+* CONJ-370 : use KeyStore default property when not using keyStore option
+* CONJ-369 : Encoding on clob column when useServerPrepStmts=true
+* CONJ-362 : fix a possible race condition MariaDbPooledConnection
+
+## 1.5.4
+* CONJ-363 : Connection.getClientInfo implementation correction to follow JDBC rules
+* CONJ-361 : PrepareStatement setString() with empty string correction.
+* CONJ-360 : replacing ManagementFactory.getRuntimeMXBean() that cause possible slow connection depending on JVM / environment
+* CONJ-359 : Metadata getColumns(...) resultSet doesnt have "IS_GENERATEDCOLUMN" info
+
+## 1.5.3
+* CONJ-358 : Permit using private key with password that differ from keyStore password
+* CONJ-356 : secure connection : use KeyStore private key and associate public keys certificates only
+* CONJ-342 : Empty clientCertificateKeyStoreUrl option correction
+* CONJ-353 : IBM jdk compatibility issue
+* CONJ-354 : Streaming issue when using procedures in PrepareStatement/Statement
+* CONJ-345 : Regression with using COLLATE keyword in PrepareStatement query
+* CONJ-352 : metadata correction on getPrecision() for numeric fields
+* CONJ-350 : make prepare fallback to client prepare if query cannot be prepared
+
+## 1.5.2
+Release version
+* CONJ-331 : clearWarnings() now throw exception on closed connection
+* CONJ-299 : PreparedStatement.setObject(Type.BIT, "1") registered as true.
+* CONJ-293 : permit named pipe connection without host
+* CONJ-333 : ResultSet.getString() of PreparedStatement return NULL When TIME column value=00:00:00
+
+RC corrections
+* CONJ-335 : Pool connection may fail to connect with good user
+* CONJ-332 : option enabledSslCipherSuites rely on java supportedCipherSuites (replacing enabledCipherSuites)
+* UTF-8 conversion correction
+
+## 1.5.1
+Release candidate version
+### Evolution
+#### Aurora host auto-discovery
+(CONJ-325)
+
+Aurora now auto discover nodes from cluster endpoint.
+
+##### Aurora endpoints
+
+Every aurora instance has a specific endpoint, i.e. a URL that identify the host. Those endpoints look like `xxx.yyy.zzz.rds.amazonaws.com`.
+
+There is another endpoint named "cluster endpoint" (format `xxx.cluster-yyy.zzz.rds.amazonaws.com`) which is assigned to the current master instance and will change when a new master is promoted.
+
+In previous version, cluster endpoint use was discouraged, since when a failover occur, this cluster endpoint can point for a limited time to a host that isn't the current master anymore. Old recommandation was to list all specific end-points, like : <br />
+{{{
+jdbc:mariadb:aurora://a.yyy.zzz.rds.amazonaws.com.com,b.yyy.zzz.rds.amazonaws.com.com/db
+}}}
+This kind of url string will still work, but now, recommended url string has to use only cluster endpoint :<br/>
+{{{
+jdbc:mariadb:aurora://xxx.cluster-yyy.zzz.rds.amazonaws.com/db
+}}}
+
+Driver will automatically discover master and slaves of this cluster from current cluster end-point during connection time. This permit to add new replicas to the cluster instance will be discovered without changing driver configuration.
+
+This discovery append at connection time, so if you are using pool framework, check if this framework as a property that controls the maximum lifetime of a connection in the pool, and set a value to avoid infinite lifetime. When this lifetime is reached, pool will discard the current connection, and create a new one (if needed). New connections will use the new replicas.
+(If connections are never discarded, new replicas will begin be used only when a failover occur)
+
+
+### Bugfix
+* CONJ-329 and CONJ-330 : rewriteBatchedStatements execute single query exceptions correction.
+  <br /><br />
+
+## 1.5.0
+Release candidate version
+### Use native SSPI windows implementation
+CONJ-295.<br />
+
+Java kerberos implementation is not well implemented with windows :
+* need a Windows registry entry (HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters\AllowTGTSessionKey) so windows shared current ticket to java.
+* java kinit must be executed to create a Ticket.
+* restriction when client with local admin rights
+* ...
+
+[see openJDK issue](https://bugs.openjdk.java.net/browse/JDK-6722928) for more information
+
+Kerberos GSSAPI implementation on Windows in now based on [Waffle](https://github.com/dblock/waffle) that support windows SSPI based on [JNA](https://github.com/java-native-access/jna).<br />
+if waffle-jna (and dependencies) is on classpath, native implementation will automatically be used.
+
+This removes all those problems
+
+### Support for TLSv1.1 and TLSv1.2
+CONJ-249/CONJ-301<br />
+
+Driver before version 1.5 support only TLSv1.<br />
+Default supported protocol are now TLSv1 and TLSv1.1, other protocols can be activated by options.
+
+MariaDB and MySQL community server permit TLSv1 and TLSv1.1.<br />
+MariaDB server from version 10.0.15 is using the openSSL library permitting TLSv1.2 (>= 5.5.41 for the 5.5 branch).
+//YaSSL doesn't support TLSv1.2, so if MariaDB server is build from sources with YaSSL, only TLSv1 and TLSv1.1 will be available, even for version > 10.0.15//
+
+TLSv1.2 can be enabled by setting option {{{enabledSslProtocolSuites}}} to values {{{"TLSv1, TLSv1.1, TLSv1.2"}}}.
+
+A new option {{{enabledSslCipherSuites}}} permit setting specific cipher.
+
+New Options :
+|=enabledSslProtocolSuites|Force TLS/SSL protocol to a specific set of TLS versions (comma separated list). <br />Example : "TLSv1, TLSv1.1, TLSv1.2"<br />//Default: TLSv1, TLSv1.1. Since 1.5.0//|
+|=enabledSslCipherSuites|Force TLS/SSL cipher (comma separated list).<br /> Example : "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"<br />//Default: use JRE ciphers. Since 1.5.0//|
+
+### Performance improvement
+[CONJ-291]<br />
+
+Different performance improvement have been done :
+* Using PreparedStatement on client side use a simple query parser to identify query parameters. This parsing was taking up to 7% of query time, reduced to 3%.
+* Better UTF-8 decoding avoiding memory consumption and gain 1-2% query time for big String.
+* client parsing optimization : rewriteBatchedStatements (insert into ab (i) values (1) and insert into ab (i) values (2) rewritten as insert into ab (i) values (1), (2))
+  is now 19% faster (Depending on queries 40-50% of CPU time was spend testing that buffer size is big enough to contain query).
+* there was some memory wastage when query return big resultset (> 10kb), slowing query.
+* ...
+
+[CONJ-320]
+Send X well established MySQL protocol without reading results, and read those X results afterwhile.
+Basically that permit to avoid a lot of 'ping-pong' between driver and server.
+
+New Options :
+|=useBatchMultiSend|PreparedStatement.executeBatch() will send many QUERY before reading result packets.//Default: true. Since 1.5.0//|
+|=useBatchMultiSendNumber|When using useBatchMultiSend, indicate maximum query that can be sent at a time.<br />//Default: 100. Since 1.5.0//|
+
+### Prepare + execute in one call
+CONJ-296
+
+When using MySQL/MariaDB prepared statement, there will be 3 exchanges with server :
+* PREPARE - Prepares statement for execution.
+* EXECUTE - Executes a prepared statement preparing by a PREPARE statement.
+* DEALLOCATE PREPARE - Releases a prepared statement.
+
+See [Server prepare documentation](https://mariadb.com/kb/en/mariadb/prepare-statement/) for more
+information.
+
+PREPARE and DEALLOCATE PREPARE are 2 additional client-server round-trip.
+Since MariaDB 10.2, a new functionality named COM-MULTI to permitting to send different task to server in one round-trip.
+Driver is using this functionality to PREPARE and EXECUTE in one client-server round-trip.
+
+### Client logging
+
+Client logging can be enabled, permitting to log query information, execution time and different failover information.
+This implementation need the standard SLF4J dependency.
+
+New Options :
+|=log|Enable log information. require Slf4j version > 1.4 dependency.<br />//Default: false. Since 1.5.0//|
+|=maxQuerySizeToLog|Only the first characters corresponding to this options size will be displayed in logs<br />//Default: 1024. Since 1.5.0//|
+|=slowQueryThresholdNanos|Will log query with execution time superior to this value (if defined )<br />//Default: 1024. Since 1.5.0//|
+|=profileSql|log query execution time.<br />//Default: false. Since 1.5.0//|
+
+
+### "LOAD DATA INFILE" Interceptors
+CONJ-305
+LOAD DATA INFILE The fastest way to load many datas is using query [LOAD DATA INFILE](https://mariadb.com/kb/en/mariadb/load-data-infile/).
+<br />Problem is using "LOAD DATA LOCAL INFILE" (ie : loading a file from client), may be a security problem :
+* A "man in the middle" proxy server can change the actual file asked from server so client will send a Local file to this proxy.
+* If someone has can execute query from client, he can have access to any file on client (according to the rights of the user running the client process).
+
+See [load-data-infile documentation](./documentation/use-mariadb-connector-j-driver.creole#load-data-infile) for more information.
+
+Interceptors can now filter LOAD DATA LOCAL INFILE query's file location to validate path / file name.
+Those interceptors:
+* Must implement interface {{{org.mariadb.jdbc.LocalInfileInterceptor}}}.
+* Use [[http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html|ServiceLoader]] implementation, so interceptors classes must be listed in file META-INF/services/org.mariadb.jdbc.LocalInfileInterceptor.
+
+Example:
+{{{
+package org.project;
+public class LocalInfileInterceptorImpl implements LocalInfileInterceptor {
+@Override
+public boolean validate(String fileName) {
+File file = new File(fileName);
+String absolutePath = file.getAbsolutePath();
+String filePath = absolutePath.substring(0,absolutePath.lastIndexOf(File.separator));
+return filePath.equals("/var/tmp/exchanges");
+}
+}
+}}}
+file META-INF/services/org.mariadb.jdbc.LocalInfileInterceptor must exist with content {{{org.project.LocalInfileInterceptorImpl}}}.
+
+You can get rid of defining the META-INF/services file using [[https://github.com/google/auto/tree/master/service|google auto-service]] framework, permitting to use annotation {{{@AutoService(LocalInfileInterceptor.class)}}} that will register the implementation as a service automatically.
+
+Using the previous example:
+{{{
+@AutoService(LocalInfileInterceptor.class)
+public class LocalInfileInterceptorImpl implements LocalInfileInterceptor {
+@Override
+public boolean validate(String fileName) {
+File file = new File(fileName);
+String absolutePath = file.getAbsolutePath();
+String filePath = absolutePath.substring(0,absolutePath.lastIndexOf(File.separator));
+return filePath.equals("/var/tmp/exchanges");
+}
+}
+}}}
+
+
+
+### Minor evolution
+* CONJ-260 : Add jdbc nString, nCharacterStream, nClob implementation
+
+### Bugfix
+* CONJ-316 : Wrong Exception thrown for ScrollType TYPE_SCROLL_INSENSITIVE
+* CONJ-298 : Error on Callable function exception when no parameter and space before parenthesis
+* CONJ-314 : Permit using Call with Statement / Prepare Statement
+  <br /><br /><br />
+## 1.4.6
+* CONJ-293] Permit named pipe connection without host
+* CONJ-309] Possible NPE on aurora when failover occur during connection initialisation
+* CONJ-312] NPE while loading a null from TIMESTAMP field using binary protocol
+* misc] batch with one parameter correction (using rewriteBatchedStatements option)
+
+## 1.4.5
+* CONJ-297] Useless memory consumption when using Statement.setQueryTimeout
+* CONJ-294] PrepareStatement on master reconnection after a failover
+* CONJ-288] using SHOW VARIABLES to replace SELECT on connection to permit connection on a galera non primary node
+* CONJ-290] Timestamps format error when using prepareStatement with options useFractionalSeconds and useServerPrepStmts
+
+## 1.4.4
+* CONJ-289] PrepareStatement on master reconnection after a failover
+* CONJ-288] using SHOW VARIABLES to replace SELECT on connection to permit connection on a galera non primary node
+
+## 1.4.3
+
+* CONJ-284] Cannot read autoincremented IDs bigger than Short.MAX_VALUE
+* CONJ-283] Parsing correction on MariaDbClientPreparedStatement - syntax error on insert values
+* CONJ-282] Handling YEARs with binary prepareStatement
+* CONJ-281] Connector/J is incompatible with Google App Engine correction
+* CONJ-278] Improve prepared statement on failover
+
+## 1.4.2
+
+* CONJ-275] Streaming result without result throw "Current position is before the first row"
+
+
+## 1.4.1
+
+
+* CONJ-274] correction to permit connection to MySQL 5.1 server
+* CONJ-273] correction when using prepareStatement without parameters and option rewriteBatchedStatements to true
+* CONJ-270] permit 65535 parameters to server preparedStatement
+* CONJ-268] update license header
+* misc] when option rewriteBatchedStatements is set to true, correction of packet separation when query size > max_allow_packet
+* misc] performance improvement for select result.
+
+## 1.4.0
+
+### Complete implementation of fetch size.
+CONJ-26
+JDBC allows to specify the number of rows fetched for a query, and this number is referred to as the fetch size
+Before version 1.4.0, query were loading all results or row by row using Statement.setFetchSize(Integer.MIN_VALUE).
+Now it's possible to set fetch size according to your need.
+Loading all results for large result sets is using a lot of memory. This functionality permit to save memory without having performance decrease.
+
+### Memory footprint improvement
+CONJ-125
+Buffers have been optimized to reduced memory footprint
+
+### CallableStatement  performance improvement.
+CONJ-209
+Calling function / procedure performance is now optimized according to query. Depending on queries, difference can be up to 300%.
+
+### Authentication evolution
+CONJ-251 Permit now new authentication possibility : [[https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/|PAM authentication]], and GSSAPI/SSPI authentication.
+
+GSSAPI/SSPI authentication authentication plugin for MariaDB permit a passwordless login.
+
+On Unix systems, GSSAPI is usually synonymous with Kerberos authentication. Windows has slightly different but very similar API called SSPI, that along with Kerberos, also supports NTLM authentication.
+See more detail in [[https://github.com/mariadb-corporation/mariadb-connector-j/blob/master/documentation/plugin/GSSAPI|GSSAPI/SSPI configuration]]
+
+### Connection attributes
+CONJ-217
+Driver information informations are now send to [[https://mariadb.com/kb/en/mariadb/performance-schema-session_connect_attrs-table/|connection attributes tables]] (performance_schema must be activated).
+A new option "connectionAttributes" permit to add client specifics data.
+
+For example when connecting with the following connection string {{{"jdbc:mariadb://localhost:3306/testj?user=root&connectionAttributes=myOption:1,mySecondOption:'jj'"}}},
+if performance_schema is activated, information about this connection will be available during the time this connection is active :
+{{{
+select * from performance_schema.session_connect_attrs where processList_id = 5
++----------------+-----------------+---------------------+------------------+
+| PROCESSLIST_ID | ATTR_NAME       | ATTR_VALUE          | ORDINAL_POSITION |
++----------------+-----------------+---------------------+------------------+
+|5               |_client_name     |MariaDB connector/J  |0                 |
+|5               |_client_version  |1.4.0-SNAPSHOT       |1                 |
+|5               |_os              |Windows 8.1          |2                 |
+|5               |_pid             |14124@portable-diego |3                 |
+|5               |_thread          |5                    |4                 |
+|5               |_java_vendor     |Oracle Corporation	 |5                 |
+|5               |_java_version    |1.7.0_79	         |6                 |
+|5               |myOption         |1	                 |7                 |
+|5               |mySecondOption   |'jj'                 |8                 |
++----------------+-----------------+---------------------+------------------+
+}}}
+
+
+## Minor evolution
+* CONJ-210 : adding a "jdbcCompliantTruncation" option to force truncation warning as SQLException.
+* CONJ-211 : when in master/slave configuration, option "assureReadOnly" will ensure that slaves are in read-only mode ( forcing transaction by a query "SET SESSION TRANSACTION READ ONLY").
+* CONJ-213 : new option "continueBatchOnError". Permit to continue batch when an exception occur : When executing a batch and an error occur, must the batch stop immediatly (default) or finish remaining batch before throwing exception.
+
+## Bugfix
+* CONJ-236 : Using a parametrized query with a smallint -1 does return the unsigned value
+* CONJ-250 : Tomcat doesn't stop when using Aurora failover configuration
+* CONJ-260 : Add jdbc nString, nCharacterStream, nClob implementation
+* CONJ-269 : handle server configuration autocommit=0
+* CONJ-271 : ResultSet.first() may throw SQLDataException: Current position is before the first row
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..952fe34
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,90 @@
+# Contributing
+
+Each pull request should address a single issue, and contain both the fix and a description of how the pull request and tests that validate that the PR fixes the issue in question.
+
+For significant feature additions, we like to have an open issue in [MariaDB JIRA](https://mariadb.atlassian.net/secure/RapidBoard.jspa?projectKey=CONJ). It is expected that discussion will have taken place in the attached issue.
+
+# Install Prerequisites
+
+These are the set of tools which are required in order to complete any build.  Follow the links to download and install them on your own before continuing.
+
+* At least one GPG Key see https://help.github.com/en/articles/generating-a-new-gpg-key
+* [Oracle JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) ( with [JCE policies](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) if using TLS/SSL)
+* IDE (eclipse / netbean / intelliJ) with maven and GIT plugins
+
+# Fork source
+
+Before downloading source, fork the project to your own repository, and use your repository as source.  
+
+## Branch signification
+
+* master : correspond to the last released version
+* develop : Develop new features for upcoming releases (compatible with java 8)
+* develop-jre6 : maintenance branch compatible with java 6 / 7 
+
+# Run local test
+
+Before any submission :
+Run the test locally : by default, you need to have a MySQL/MariaDB server on localhost:3306 with a database named "testj" and a user root without password.
+so you can run 
+    
+```script
+    mvn test
+```
+    
+You can change this parameter by adding -DdbUrl parameter. like : 
+ 
+```script
+    mvn test -DdbUrl=jdbc:mariadb://127.0.0.1:3306/testj?user=root&password=*****
+```
+    
+You can launch a specific test by adding -Dtest
+
+```script
+    mvn test -Dtest=org.mariadb.jdbc.JdbcParserTest
+```
+    
+When all test are passing, you can package project.
+Additional tests , like javadoc formatting, code style validation will be done : 
+  
+```script
+    mvn package -Dmaven.test.skip=true
+```
+    
+If operation succeed, a new mariadb-java-client jar will be on the target folder.
+  
+# Run travis test
+    
+You can activate travis to validate your repository. 
+The advantage of travis compare to running test locally is that it will launch tests for a combination of those parameters : 
+
+jdk:
+* oraclejdk8
+and if your work is on develop-jre6 branch
+* openjdk6
+* openjdk7
+
+server :
+* MariaDB 5.5
+* MariaDB 10.0
+* MariaDB 10.1
+* MariaDB 10.2
+* MySQL 5.6
+* MySQL 5.7
+
+max_allowed_packet : (this permit to check multipacket send)
+* 8M
+* 20M
+* 40M
+
+For that, you have to go on [travis website](https://travis-ci.org), connect with your github account, and activate your mariadb-connector-j repository.
+After this step, every push to your repository will launch a travis test. 
+
+## Submitting a request
+
+When your repository has the correction/change done, you can submit a pull request by clicking the "Pull request" button on github. 
+Please detail the operation done in your request. 
+
+## License
+
+Distributed under the terms of the GNU Library or "Lesser" General Public License (LGPL).
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..118b572
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,502 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bb05156
--- /dev/null
+++ b/README.md
@@ -0,0 +1,63 @@
+<p align="center">
+  <a href="https://mariadb.com/">
+    <img src="https://mariadb.com/kb/static/images/logo-2018-black.png">
+  </a>
+</p>
+
+# MariaDB java connector
+
+MariaDB java connector is a JDBC 4.2 compatible driver, used to connect applications developed in Java to MariaDB and MySQL databases. MariaDB Connector/J is LGPL licensed.
+
+Tracker link <a href="https://jira.mariadb.org/projects/CONJ/issues/">https://jira.mariadb.org/projects/CONJ/issues/</a>
+
+## Status
+[![Linux Build](https://travis-ci.com/mariadb-corporation/mariadb-connector-j.svg?branch=master)](https://app.travis-ci.com/github/mariadb-corporation/mariadb-connector-j)
+[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.mariadb.jdbc/mariadb-java-client/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.mariadb.jdbc/mariadb-java-client)
+[![License (LGPL version 2.1)](https://img.shields.io/badge/license-GNU%20LGPL%20version%202.1-green.svg?style=flat-square)](http://opensource.org/licenses/LGPL-2.1)
+[![codecov][codecov-image]][codecov-url]
+
+## Obtaining the driver
+
+For java 8+ :
+
+The driver (jar) can be downloaded from [mariadb connector download](https://mariadb.com/downloads/#connectors)
+or maven : 
+```script
+<dependency>
+	<groupId>org.mariadb.jdbc</groupId>
+	<artifactId>mariadb-java-client</artifactId>
+	<version>3.1.2</version>
+</dependency>
+```
+
+
+Development snapshot are available on sonatype nexus repository
+```script
+<repositories>
+    <repository>
+        <id>sonatype-nexus-snapshots</id>
+        <name>Sonatype Nexus Snapshots</name>
+        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    </repository>
+</repositories>
+
+<dependencies>
+    <dependency>
+        <groupId>org.mariadb.jdbc</groupId>
+        <artifactId>mariadb-java-client</artifactId>
+        <version>3.1.3-SNAPSHOT</version>
+    </dependency>
+</dependencies>
+```
+
+## Documentation
+
+For a Getting started guide, API docs, recipes,  etc. see the 
+* [About MariaDB connector/J](https://mariadb.com/kb/en/about-mariadb-connector-j/)
+* [Install driver](https://mariadb.com/kb/en/installing-mariadb-connectorj/)
+* [Changelog](/CHANGELOG.md)
+* [Failover and high-availability](https://mariadb.com/kb/en/failover-and-high-availability-with-mariadb-connector-j/)
+
+
+[codecov-image]:https://codecov.io/gh/mariadb-corporation/mariadb-connector-j/branch/master/graph/badge.svg
+[codecov-url]:https://codecov.io/gh/mariadb-corporation/mariadb-connector-j
diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..f189fda
--- /dev/null
+++ b/bnd.bnd
@@ -0,0 +1,21 @@
+Export-Package: org.mariadb.jdbc;org.mariadb.jdbc.client;org.mariadb.jdbc.client.util;org.mariadb.jdbc.client.socket;org.mariadb.jdbc.message;org.mariadb.jdbc.type;org.mariadb.jdbc.export;org.mariadb.jdbc.plugin;org.mariadb.jdbc.plugin.codec;org.mariadb.jdbc.plugin.authentication.standard;org.mariadb.jdbc.plugin.authentication.addon;org.mariadb.jdbc.plugin.credential.aws;org.mariadb.jdbc.plugin.credential.env;org.mariadb.jdbc.plugin.credential.system;org.mariadb.jdbc.plugin.tls.main
+
+Import-Package: \
+    javax.naming,\
+    javax.naming.ldap,\
+    javax.management,\
+    javax.sql,\
+    org.slf4j;resolution:=optional, \
+    javax.net;resolution:=optional,\
+    javax.net.ssl;resolution:=optional,\
+    com.sun.jna;resolution:=optional,\
+    com.sun.jna.platform.win32;resolution:=optional,\
+    javax.transaction.xa;resolution:=optional,\
+    waffle.windows.auth;resolution:=optional,\
+    waffle.windows.auth.impl;resolution:=optional,\
+    org.ietf.jgss;resolution:=optional,\
+    javax.security.auth.login;resolution:=optional,\
+    javax.security.auth.x500;resolution:=optional,\
+    software.amazon.awssdk.*;resolution:=optional
+
+-fixupmessages: "Classes found in the wrong directory:";is:=ignore
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..a107d78
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,462 @@
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.mariadb.jdbc</groupId>
+    <artifactId>mariadb-java-client</artifactId>
+    <packaging>jar</packaging>
+    <name>mariadb-java-client</name>
+    <version>3.1.2</version>
+    <description>JDBC driver for MariaDB and MySQL</description>
+    <url>https://mariadb.com/kb/en/mariadb/about-mariadb-connector-j/</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jmh.version>1.34</jmh.version>
+        <junit.version>5.8.2</junit.version>
+        <junit-pioneer.version>1.5.0</junit-pioneer.version>
+        <assertj.version>3.22.0</assertj.version>
+        <osgi.version>6.0.0</osgi.version>
+        <osgi.compendium.version>5.0.0</osgi.compendium.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <logback.version>1.4.4</logback.version>
+        <jacoco.version>0.8.8</jacoco.version>
+        <waffle-jna.version>3.2.0</waffle-jna.version>
+        <mysql-connector-java.version>8.0.31</mysql-connector-java.version>
+        <bnd-maven-plugin.version>6.3.1</bnd-maven-plugin.version>
+    </properties>
+
+    <licenses>
+        <license>
+            <name>LGPL-2.1</name>
+        </license>
+    </licenses>
+
+    <organization>
+        <name>mariadb.com</name>
+        <url>https://mariadb.com</url>
+    </organization>
+
+    <developers>
+        <developer>
+            <id>mariadbJdbcDevelopers</id>
+            <name>mariadb jdbc developers</name>
+            <url>http://mariadb.org/</url>
+        </developer>
+    </developers>
+
+    <scm>
+        <connection>scm:git:git://github.com/mariadb-corporation/mariadb-connector-j.git</connection>
+        <url>https://github.com/mariadb-corporation/mariadb-connector-j</url>
+        <developerConnection>scm:git:git@github.com:MariaDB/mariadb-connector-j.git
+        </developerConnection>
+    </scm>
+
+    <issueManagement>
+        <system>JIRA</system>
+        <url>https://mariadb.atlassian.net/browse/CONJ</url>
+    </issueManagement>
+
+    <distributionManagement>
+        <snapshotRepository>
+            <id>ossrh</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+    <dependencyManagement>
+        <dependencies>
+
+            <dependency>
+                <groupId>org.junit</groupId>
+                <artifactId>junit-bom</artifactId>
+                <version>${junit.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <dependency>
+                <groupId>software.amazon.awssdk</groupId>
+                <artifactId>bom</artifactId>
+                <version>2.18.10</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+
+    </dependencyManagement>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.10.1</version>
+                <configuration>
+                    <showWarnings>true</showWarnings>
+                    <compilerArgs>
+                        <arg>-Xlint:all,-options,-path,-processing</arg>
+                    </compilerArgs>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>compile-java-8</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>compile-java-9</id>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <configuration>
+                            <release>9</release>
+                            <source>9</source>
+                            <target>9</target>
+                            <compileSourceRoots>
+                                <compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
+                            </compileSourceRoots>
+                            <multiReleaseOutput>true</multiReleaseOutput>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>compile-java-11</id>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <configuration>
+                            <release>11</release>
+                            <source>11</source>
+                            <target>11</target>
+                            <compileSourceRoots>
+                                <compileSourceRoot>${project.basedir}/src/main/java11</compileSourceRoot>
+                            </compileSourceRoots>
+                            <multiReleaseOutput>true</multiReleaseOutput>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>3.4.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <excludePackageNames>
+                        org.mariadb.jdbc.client,org.mariadb.jdbc.codec,org.mariadb.jdbc.message,org.mariadb.jdbc.util,org.mariadb.jdbc.plugin.authentication.standard.ed25519,org.mariadb.jdbc.plugin.authentication.standard.ed25519.*
+                    </excludePackageNames>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>attach-javadocs</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.3.0</version>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Multi-Release>true</Multi-Release>
+                            <Export-Package>org.mariadb.jdbc</Export-Package>
+                            <Import-Package>
+                                javax.naming,javax.naming.ldap,javax.management,javax.sql,javax.net;resolution:=optional,javax.net.ssl;resolution:=optional,javax.transaction.xa;resolution:=optional,waffle.windows.auth;resolution:=optional,waffle.windows.auth.impl;resolution:=optional,org.ietf.jgss;resolution:=optional,javax.security.auth.login;resolution:=optional,javax.security.auth.x500;resolution:=optional,software.amazon.awssdk.*;resolution:=optional,org.slf4j;resolution:=optional
+                            </Import-Package>
+                        </manifestEntries>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.2.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.sonatype.plugins</groupId>
+                <artifactId>nexus-staging-maven-plugin</artifactId>
+                <version>1.6.13</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <phase>deploy</phase>
+                    </execution>
+                </executions>
+                <configuration>
+                    <serverId>ossrh</serverId>
+                    <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+                    <autoReleaseAfterClose>false</autoReleaseAfterClose>
+                    <stagingProgressTimeoutMinutes>15</stagingProgressTimeoutMinutes>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-gpg-plugin</artifactId>
+                <version>3.0.1</version>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>sign</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>com.coveo</groupId>
+                <artifactId>fmt-maven-plugin</artifactId>
+                <version>2.13</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>format</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M7</version>
+            </plugin>
+
+            <plugin>
+                <groupId>biz.aQute.bnd</groupId>
+                <artifactId>bnd-maven-plugin</artifactId>
+                <version>${bnd-maven-plugin.version}</version>
+                <configuration>
+                    <bndfile>bnd.bnd</bndfile>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>bnd-process</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.github.waffle</groupId>
+            <artifactId>waffle-jna</artifactId>
+            <version>${waffle-jna.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.junit-pioneer</groupId>
+            <artifactId>junit-pioneer</artifactId>
+            <version>${junit-pioneer.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>2.0.3</version>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>${logback.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>${osgi.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>${osgi.compendium.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>rds</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+    </dependencies>
+
+
+    <profiles>
+        <profile>
+            <id>default</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+
+            <build>
+                <plugins>
+
+                    <plugin>
+                        <groupId>org.jacoco</groupId>
+                        <artifactId>jacoco-maven-plugin</artifactId>
+                        <version>${jacoco.version}</version>
+                        <configuration>
+                            <excludes>
+                                <exclude>META-INF/**</exclude>
+                            </excludes>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>jacoco-initialize</id>
+                                <goals>
+                                    <goal>prepare-agent</goal>
+                                </goals>
+                            </execution>
+                            <execution>
+                                <id>report</id>
+                                <phase>test</phase>
+                                <goals>
+                                    <goal>report</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>bench</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.openjdk.jmh</groupId>
+                    <artifactId>jmh-core</artifactId>
+                    <version>${jmh.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.openjdk.jmh</groupId>
+                    <artifactId>jmh-generator-annprocess</artifactId>
+                    <version>${jmh.version}</version>
+                </dependency>
+
+                <dependency>
+                    <groupId>mysql</groupId>
+                    <artifactId>mysql-connector-java</artifactId>
+                    <version>${mysql-connector-java.version}</version>
+                </dependency>
+
+            </dependencies>
+
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <version>3.0.0</version>
+                        <executions>
+                            <execution>
+                                <id>add-source</id>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-source</goal>
+                                </goals>
+                                <configuration>
+                                    <sources>
+                                        <source>src/benchmark/java</source>
+                                    </sources>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>add-resource</id>
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>add-resource</goal>
+                                </goals>
+                                <configuration>
+                                    <resources>
+                                        <resource>
+                                            <directory>src/benchmark/resources</directory>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-shade-plugin</artifactId>
+                        <version>3.2.4</version>
+                        <configuration>
+                            <finalName>benchmarks</finalName>
+                            <transformers>
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>org.openjdk.jmh.Main</mainClass>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>shade</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/src/benchmark/README.md b/src/benchmark/README.md
new file mode 100644
index 0000000..1a5158f
--- /dev/null
+++ b/src/benchmark/README.md
@@ -0,0 +1,33 @@
+<p align="center">
+  <a href="https://mariadb.com/">
+    <img src="https://mariadb.com/kb/static/images/logo-2018-black.png">
+  </a>
+</p>
+
+# Benchmark
+
+How to run : 
+```script
+mvn clean package -P bench -DskipTests
+
+# run all benchmarks
+nohup java -Duser.country=US -Duser.language=en -jar target/benchmarks.jar > log.txt
+
+# run a specific benchmark
+java -Duser.country=US -Duser.language=en -jar target/benchmarks.jar "Select_100_cols"
+```
+
+Configuration by system properties :
+* TEST_HOST: Hostname. default "localhost"
+* TEST_PORT: port. default 3306
+* TEST_USERNAME: user name. default "root"
+* TEST_PASSWORD: password. default ""
+* TEST_DATABASE: database. default "testj"
+* TEST_OTHER: permit adding connection string options. default ""
+
+example: 
+```script
+mvn clean package -P bench -Dmaven.test.skip
+java -DTEST_PORT=3307 -Duser.country=US -Duser.language=en -jar target/benchmarks.jar "Select_100_cols"
+```
+
diff --git a/src/benchmark/java/org/mariadb/jdbc/Common.java b/src/benchmark/java/org/mariadb/jdbc/Common.java
new file mode 100644
index 0000000..8a43e13
--- /dev/null
+++ b/src/benchmark/java/org/mariadb/jdbc/Common.java
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.*;
+
+@State(Scope.Benchmark)
+@Warmup(iterations = 10, timeUnit = TimeUnit.SECONDS, time = 1)
+@Measurement(iterations = 10, timeUnit = TimeUnit.SECONDS, time = 1)
+@Fork(value = 5)
+@Threads(value = 1) // detecting CPU count
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class Common {
+
+  // conf
+  public static final String host = System.getProperty("TEST_HOST", "localhost");
+  public static final int port = Integer.parseInt(System.getProperty("TEST_PORT", "3306"));
+  public static final String username = System.getProperty("TEST_USERNAME", "root");
+  public static final String password = System.getProperty("TEST_PASSWORD", "");
+  public static final String database = System.getProperty("TEST_DATABASE", "testj");
+  public static final String other = System.getProperty("TEST_OTHER", "");
+
+  static {
+    new SetupData();
+  }
+
+  @State(Scope.Thread)
+  public static class MyState {
+
+    // connections
+    protected Connection connectionText;
+    protected Connection connectionTextRewrite;
+
+    protected Connection connectionBinary;
+
+    protected Connection connectionBinaryNoPipeline;
+    protected Connection connectionBinaryNoCache;
+
+    @Param({"mysql", "mariadb"})
+    String driver;
+
+    @Setup(Level.Trial)
+    public void createConnections() throws Exception {
+
+      String className;
+      switch (driver) {
+        case "mysql":
+          className = "com.mysql.cj.jdbc.Driver";
+          break;
+        case "mariadb":
+          className = "org.mariadb.jdbc.Driver";
+          break;
+        default:
+          throw new RuntimeException("wrong param");
+      }
+      try {
+        String jdbcBase =
+            "jdbc:%s://%s:%s/%s?user=%s&password=%s&sslMode=DISABLED&useServerPrepStmts=%s&cachePrepStmts=%s&serverTimezone=UTC%s";
+        String jdbcUrlText =
+            String.format(
+                jdbcBase, driver, host, port, database, username, password, false, false, other);
+        String jdbcUrlBinary =
+            String.format(
+                jdbcBase, driver, host, port, database, username, password, true, true, other);
+
+        connectionText =
+            ((java.sql.Driver) Class.forName(className).getDeclaredConstructor().newInstance())
+                .connect(jdbcUrlText, new Properties());
+        String jdbcUrlTextRewrite =
+            String.format(
+                jdbcBase,
+                driver,
+                host,
+                port,
+                database,
+                username,
+                password,
+                false,
+                false,
+                "&rewriteBatchedStatements=true&useBulkStmts=false" + other);
+        connectionTextRewrite =
+            ((java.sql.Driver) Class.forName(className).getDeclaredConstructor().newInstance())
+                .connect(jdbcUrlTextRewrite, new Properties());
+        connectionBinary =
+            ((java.sql.Driver) Class.forName(className).getDeclaredConstructor().newInstance())
+                .connect(jdbcUrlBinary, new Properties());
+
+        String jdbcUrlBinaryNoCache =
+            String.format(
+                jdbcBase,
+                driver,
+                host,
+                port,
+                database,
+                username,
+                password,
+                true,
+                false,
+                "&prepStmtCacheSize=0" + other);
+
+        connectionBinaryNoCache =
+            ((java.sql.Driver) Class.forName(className).getDeclaredConstructor().newInstance())
+                .connect(jdbcUrlBinaryNoCache, new Properties());
+
+        String jdbcUrlBinaryNoCacheNoPipeline =
+            String.format(
+                jdbcBase,
+                driver,
+                host,
+                port,
+                database,
+                username,
+                password,
+                true,
+                true,
+                "&prepStmtCacheSize=0&cachePrepStmts=false&disablePipeline=true" + other);
+        connectionBinaryNoPipeline =
+            ((java.sql.Driver) Class.forName(className).getDeclaredConstructor().newInstance())
+                .connect(jdbcUrlBinaryNoCacheNoPipeline, new Properties());
+      } catch (SQLException e) {
+        e.printStackTrace();
+        throw new RuntimeException(e);
+      }
+    }
+
+    @TearDown(Level.Trial)
+    public void doTearDown() throws SQLException {
+      connectionText.close();
+      connectionBinary.close();
+      connectionTextRewrite.close();
+      connectionBinaryNoCache.close();
+      connectionBinaryNoPipeline.close();
+    }
+  }
+
+  public static class SetupData {
+    static {
+      try {
+        try (Connection conn =
+            DriverManager.getConnection(
+                String.format(
+                    "jdbc:mariadb://%s:%s/%s?user=%s&password=%s",
+                    host, port, database, username, password))) {
+          Statement stmt = conn.createStatement();
+          try {
+            stmt.executeQuery("INSTALL SONAME 'ha_blackhole'");
+          } catch (SQLException e) {
+            // eat
+          }
+          stmt.executeUpdate("DROP TABLE IF EXISTS testBlackHole");
+          stmt.executeUpdate("DROP TABLE IF EXISTS test100");
+
+          try {
+            stmt.executeUpdate(
+                "CREATE TABLE testBlackHole (id INT, t VARCHAR(256)) ENGINE = BLACKHOLE");
+          } catch (SQLException e) {
+            stmt.executeUpdate("CREATE TABLE testBlackHole (id INT, t VARCHAR(256))");
+          }
+
+          StringBuilder sb = new StringBuilder("CREATE TABLE test100 (i1 int");
+          StringBuilder sb2 = new StringBuilder("INSERT INTO test100 value (1");
+          for (int i = 2; i <= 100; i++) {
+            sb.append(",i").append(i).append(" int");
+            sb2.append(",").append(i);
+          }
+          sb.append(")");
+          sb2.append(")");
+          stmt.executeUpdate(sb.toString());
+          stmt.executeUpdate(sb2.toString());
+
+          stmt.execute("DROP TABLE IF EXISTS perfTestTextBatch");
+          try {
+            stmt.execute("INSTALL SONAME 'ha_blackhole'");
+          } catch (SQLException e) {
+          }
+
+          String createTable =
+              "CREATE TABLE perfTestTextBatch (id MEDIUMINT NOT NULL AUTO_INCREMENT,t0 text,"
+                  + " PRIMARY KEY (id)) COLLATE='utf8mb4_unicode_ci'";
+          try {
+            stmt.execute(createTable + " ENGINE = BLACKHOLE");
+          } catch (SQLException e) {
+            stmt.execute(createTable);
+          }
+        }
+      } catch (SQLException e) {
+        e.printStackTrace();
+      }
+    }
+  }
+}
diff --git a/src/benchmark/java/org/mariadb/jdbc/Do_1.java b/src/benchmark/java/org/mariadb/jdbc/Do_1.java
new file mode 100644
index 0000000..ef6466d
--- /dev/null
+++ b/src/benchmark/java/org/mariadb/jdbc/Do_1.java
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.Statement;
+import org.openjdk.jmh.annotations.Benchmark;
+
+public class Do_1 extends Common {
+
+  @Benchmark
+  public int run(MyState state) throws Throwable {
+    try (Statement st = state.connectionText.createStatement()) {
+      return st.executeUpdate("DO 1");
+    }
+  }
+}
diff --git a/src/benchmark/java/org/mariadb/jdbc/Do_1000_params.java b/src/benchmark/java/org/mariadb/jdbc/Do_1000_params.java
new file mode 100644
index 0000000..a31af30
--- /dev/null
+++ b/src/benchmark/java/org/mariadb/jdbc/Do_1000_params.java
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import org.openjdk.jmh.annotations.Benchmark;
+
+public class Do_1000_params extends Common {
+
+  private static final String sql;
+
+  static {
+    StringBuilder sb = new StringBuilder("do ?");
+    for (int i = 1; i < 1000; i++) {
+      sb.append(",?");
+    }
+    sql = sb.toString();
+  }
+
+  @Benchmark
+  public int text(MyState state) throws Throwable {
+    return run(state.connectionText);
+  }
+
+  //    @Benchmark
+  //    public int binary(MyState state) throws Throwable {
+  //        return run(state.connectionBinary);
+  //    }
+
+  private int run(Connection con) throws Throwable {
+
+    try (PreparedStatement st = con.prepareStatement(sql)) {
+      for (int i = 1; i <= 1000; i++) {
+        st.setInt(i, i);
+      }
+      return st.executeUpdate();
+    }
+  }
+}
diff --git a/src/benchmark/java/org/mariadb/jdbc/Insert_batch.java b/src/benchmark/java/org/mariadb/jdbc/Insert_batch.java
new file mode 100644
index 0000000..400c2b9
--- /dev/null
+++ b/src/benchmark/java/org/mariadb/jdbc/Insert_batch.java
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.openjdk.jmh.annotations.Benchmark;
+
+public class Insert_batch extends Common {
+
+  static final List<String> chars = new ArrayList<>();
+
+  static {
+    chars.addAll(Arrays.asList("123456789abcdefghijklmnop\\Z".split("")));
+    chars.add("😎");
+    chars.add("🌶");
+    chars.add("🎤");
+    chars.add("🥂");
+  }
+
+  public static String randomString(int length) {
+    StringBuilder result = new StringBuilder();
+    for (int i = length; i > 0; --i)
+      result.append(chars.get(Math.round((int) Math.random() * (chars.size() - 1))));
+    return result.toString();
+  }
+
+  @Benchmark
+  public int[] binary(MyState state) throws Throwable {
+    return run(state.connectionBinary);
+  }
+
+  @Benchmark
+  public int[] rewrite(MyState state) throws Throwable {
+    return run(state.connectionTextRewrite);
+  }
+
+  private int[] run(Connection con) throws Throwable {
+    String s = randomString(100);
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO perfTestTextBatch(t0) VALUES (?)")) {
+      for (int i = 0; i < 100; i++) {
+        prep.setString(1, s);
+        prep.addBatch();
+      }
+      return prep.executeBatch();
+    }
+  }
+}
diff --git a/src/benchmark/java/org/mariadb/jdbc/Select_1.java b/src/benchmark/java/org/mariadb/jdbc/Select_1.java
new file mode 100644
index 0000000..32ce59d
--- /dev/null
+++ b/src/benchmark/java/org/mariadb/jdbc/Select_1.java
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.Statement;
+import org.openjdk.jmh.annotations.Benchmark;
+
+public class Select_1 extends Common {
+
+  @Benchmark
+  public int run(MyState state) throws Throwable {
+    try (Statement st = state.connectionText.createStatement()) {
+      ResultSet rs = st.executeQuery("select 1");
+      rs.next();
+      return rs.getInt(1);
+    }
+  }
+}
diff --git a/src/benchmark/java/org/mariadb/jdbc/Select_1000_Rows.java b/src/benchmark/java/org/mariadb/jdbc/Select_1000_Rows.java
new file mode 100644
index 0000000..8a298a8
--- /dev/null
+++ b/src/benchmark/java/org/mariadb/jdbc/Select_1000_Rows.java
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import org.openjdk.jmh.annotations.Benchmark;
+
+public class Select_1000_Rows extends Common {
+  private static final String sql =
+      "select seq, 'abcdefghijabcdefghijabcdefghijaa' from seq_1_to_1000";
+
+  @Benchmark
+  public int text(MyState state) throws Throwable {
+    return run(state.connectionText);
+  }
+
+  @Benchmark
+  public int binary(MyState state) throws Throwable {
+    return run(state.connectionBinary);
+  }
+
+  private int run(Connection con) throws Throwable {
+    try (PreparedStatement st = con.prepareStatement(sql)) {
+      ResultSet rs = st.executeQuery();
+      int i = 0;
+      while (rs.next()) {
+        i = rs.getInt(1);
+        rs.getString(2);
+      }
+      return i;
+    }
+  }
+}
diff --git a/src/benchmark/java/org/mariadb/jdbc/Select_100_cols.java b/src/benchmark/java/org/mariadb/jdbc/Select_100_cols.java
new file mode 100644
index 0000000..94c6114
--- /dev/null
+++ b/src/benchmark/java/org/mariadb/jdbc/Select_100_cols.java
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.*;
+import java.sql.Connection;
+import org.openjdk.jmh.annotations.Benchmark;
+
+public class Select_100_cols extends Common {
+
+  @Benchmark
+  public int[] text(MyState state) throws Throwable {
+    return run(state.connectionText);
+  }
+
+  @Benchmark
+  public int[] binary(MyState state) throws Throwable {
+    return run(state.connectionBinary);
+  }
+
+  @Benchmark
+  public int[] binaryNoCache(MyState state) throws Throwable {
+    return run(state.connectionBinaryNoCache);
+  }
+
+  @Benchmark
+  public int[] binaryNoPipeline(MyState state) throws Throwable {
+    return run(state.connectionBinaryNoPipeline);
+  }
+
+  private int[] run(Connection con) throws Throwable {
+
+    try (PreparedStatement prep = con.prepareStatement("select * FROM test100")) {
+      ResultSet rs = prep.executeQuery();
+      rs.next();
+      int[] objs = new int[100];
+      for (int i = 0; i < 100; i++) {
+        objs[i] = rs.getInt(i + 1);
+      }
+      return objs;
+    }
+  }
+}
diff --git a/src/benchmark/resources/logback-test.xml b/src/benchmark/resources/logback-test.xml
new file mode 100644
index 0000000..3dbbecb
--- /dev/null
+++ b/src/benchmark/resources/logback-test.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+  <appender class="ch.qos.logback.core.ConsoleAppender" name="STDOUT">
+    <encoder>
+      <pattern>%d{yyyy-MM-dd} | %d{HH:mm:ss.SSS} | %-20.20thread | %5p | %logger{25} | %m%n
+      </pattern>
+    </encoder>
+  </appender>
+
+  <logger level="ERROR" name="org.mariadb.jdbc"/>
+
+  <root level="WARN">
+    <appender-ref ref="STDOUT"/>
+  </root>
+
+</configuration>
\ No newline at end of file
diff --git a/src/main/java/org/mariadb/jdbc/BaseCallableStatement.java b/src/main/java/org/mariadb/jdbc/BaseCallableStatement.java
new file mode 100644
index 0000000..92d0e3d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/BaseCallableStatement.java
@@ -0,0 +1,2832 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.sql.Date;
+import java.sql.Statement;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.client.result.Result;
+import org.mariadb.jdbc.codec.Parameter;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.util.ParameterList;
+
+/** Common methods for function/stored procedure */
+public abstract class BaseCallableStatement extends ServerPreparedStatement
+    implements CallableStatement {
+
+  /** Database name */
+  protected final String databaseName;
+
+  /** Procedure name */
+  protected final String procedureName;
+
+  /** parameter metadata */
+  protected CallableParameterMetaData parameterMetaData = null;
+
+  /** Declared output parameters */
+  protected final Set<Integer> outputParameters = new HashSet<>();
+
+  /** output parameter result */
+  private Result outputResult = null;
+
+  /**
+   * Constructor
+   *
+   * @param sql sql command
+   * @param con connection
+   * @param lock thread safe lock
+   * @param databaseName database name
+   * @param procedureName procedure name
+   * @param canUseServerTimeout indicate if server support server timeout
+   * @param canUseServerMaxRows indicate if server support server max rows
+   * @param canCachePrepStmts can cache server prepared result
+   * @param resultSetType resultset type
+   * @param resultSetConcurrency resultset concurrency
+   * @param defaultFetchSize default fetch size
+   * @throws SQLException if prepare fails
+   */
+  public BaseCallableStatement(
+      String sql,
+      Connection con,
+      ReentrantLock lock,
+      String databaseName,
+      String procedureName,
+      boolean canUseServerTimeout,
+      boolean canUseServerMaxRows,
+      boolean canCachePrepStmts,
+      int resultSetType,
+      int resultSetConcurrency,
+      int defaultFetchSize)
+      throws SQLException {
+    super(
+        sql,
+        con,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        canCachePrepStmts,
+        Statement.RETURN_GENERATED_KEYS,
+        resultSetType,
+        resultSetConcurrency,
+        defaultFetchSize);
+    this.databaseName = databaseName;
+    this.procedureName = procedureName;
+  }
+
+  /**
+   * Indicate if callable statement is a function or a stored procedure
+   *
+   * @return indicate if is a function
+   */
+  public abstract boolean isFunction();
+
+  /**
+   * Output result without output parameters
+   *
+   * @param i index
+   * @throws SQLException if any exception
+   */
+  protected void outputResultFromRes(int i) throws SQLException {
+    this.outputResult = (Result) this.results.remove(this.results.size() - i);
+    this.outputResult.next();
+  }
+
+  /**
+   * Registers the OUT parameter in ordinal position <code>parameterIndex</code> to the JDBC type
+   * <code>sqlType</code>. All OUT parameters must be registered before a stored procedure is
+   * executed.
+   *
+   * <p>The JDBC type specified by <code>sqlType</code> for an OUT parameter determines the Java
+   * type that must be used in the <code>get</code> method to read the value of that parameter.
+   *
+   * <p>If the JDBC type expected to be returned to this output parameter is specific to this
+   * particular database, <code>sqlType</code> should be <code>java.sql.Types.OTHER</code>. The
+   * method {@link #getObject} retrieves the value.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param sqlType the JDBC type code defined by <code>java.sql.Types</code>. If the parameter is
+   *     of JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>, the version of <code>
+   *     registerOutParameter</code> that accepts a scale value should be used.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type
+   * @see Types
+   */
+  @Override
+  public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
+    checkIndex(parameterIndex);
+    outputParameters.add(parameterIndex);
+    if (!parameters.containsKey(parameterIndex - 1))
+      parameters.set(parameterIndex - 1, Parameter.NULL_PARAMETER);
+  }
+
+  private void checkIndex(int index) throws SQLException {
+    if (index <= 0
+        || (prepareResult != null
+            && index > (prepareResult.getParameters().length + (isFunction() ? 1 : 0)))
+        || (prepareResult == null
+            && parameterMetaData != null
+            && index > parameterMetaData.getParameterCount())) {
+      throw exceptionFactory().create(String.format("wrong parameter index %s", index));
+    }
+  }
+
+  /**
+   * Registers the parameter in ordinal position <code>parameterIndex</code> to be of JDBC type
+   * <code>sqlType</code>. All OUT parameters must be registered before a stored procedure is
+   * executed.
+   *
+   * <p>The JDBC type specified by <code>sqlType</code> for an OUT parameter determines the Java
+   * type that must be used in the <code>get</code> method to read the value of that parameter.
+   *
+   * <p>This version of <code>registerOutParameter</code> should be used when the parameter is of
+   * JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param sqlType the SQL type code defined by <code>java.sql.Types</code>.
+   * @param scale the desired number of digits to the right of the decimal point. It must be greater
+   *     than or equal to zero.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type
+   * @see Types
+   */
+  @Override
+  public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException {
+    registerOutParameter(parameterIndex, sqlType);
+  }
+
+  @Override
+  public void clearParameters() throws SQLException {
+    checkNotClosed();
+    parameters = new ParameterList();
+    outputParameters.stream().forEach(index -> parameters.set(index - 1, Parameter.NULL_PARAMETER));
+  }
+
+  /**
+   * Retrieves whether the last OUT parameter read had the value of SQL <code>NULL</code>. Note that
+   * this method should be called only after calling a getter method; otherwise, there is no value
+   * to use in determining whether it is <code>null</code> or not.
+   *
+   * @return <code>true</code> if the last parameter read was SQL <code>NULL</code>; <code>false
+   *     </code> otherwise
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>CallableStatement</code>
+   */
+  @Override
+  public boolean wasNull() throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.wasNull();
+  }
+
+  private int idxToOutIdx(int idx) throws SQLException {
+    int outputIndex = 1;
+    if (idx < 1) throw exceptionFactory().create(String.format("wrong index %s", idx));
+    if (!outputParameters.contains(idx))
+      throw exceptionFactory().create(String.format("index %s not declared as output", idx));
+    for (int i = 1; i < idx; i++) {
+      if (outputParameters.contains(i)) outputIndex++;
+    }
+
+    return outputIndex;
+  }
+
+  /**
+   * Check if statement is closed, and throw exception if so.
+   *
+   * @throws SQLException if statement close
+   */
+  protected void checkOutputResult() throws SQLException {
+    if (outputResult == null) {
+      throw exceptionFactory().create("No output result");
+    }
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>CHAR</code>, <code>VARCHAR</code>, or <code>
+   * LONGVARCHAR</code> parameter as a <code>String</code> in the Java programming language.
+   *
+   * <p>For the fixed-length type JDBC <code>CHAR</code>, the <code>String</code> object returned
+   * has exactly the same value the SQL <code>CHAR</code> value had in the database, including any
+   * padding added by the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setString
+   */
+  @Override
+  public String getString(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getString(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>BIT</code> or <code>BOOLEAN</code> parameter
+   * as a <code>boolean</code> in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>false
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setBoolean
+   */
+  @Override
+  public boolean getBoolean(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getBoolean(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>TINYINT</code> parameter as a <code>byte
+   * </code> in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setByte
+   */
+  @Override
+  public byte getByte(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getByte(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>SMALLINT</code> parameter as a <code>short
+   * </code> in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setShort
+   */
+  @Override
+  public short getShort(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getShort(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>INTEGER</code> parameter as an <code>int
+   * </code> in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setInt
+   */
+  @Override
+  public int getInt(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getInt(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>BIGINT</code> parameter as a <code>long</code>
+   * in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setLong
+   */
+  @Override
+  public long getLong(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getLong(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>FLOAT</code> parameter as a <code>float</code>
+   * in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setFloat
+   */
+  @Override
+  public float getFloat(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getFloat(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>DOUBLE</code> parameter as a <code>double
+   * </code> in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setDouble
+   */
+  @Override
+  public double getDouble(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getDouble(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a <code>
+   * java.math.BigDecimal</code> object with <i>scale</i> digits to the right of the decimal point.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param scale the number of digits to the right of the decimal point
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setBigDecimal
+   * @deprecated use <code>getBigDecimal(int parameterIndex)</code> or <code>
+   *     getBigDecimal(String parameterName)</code>
+   */
+  @Override
+  @Deprecated
+  public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getBigDecimal(idxToOutIdx(parameterIndex), scale);
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>BINARY</code> or <code>VARBINARY</code>
+   * parameter as an array of <code>byte</code> values in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setBytes
+   */
+  @Override
+  public byte[] getBytes(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getBytes(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>DATE</code> parameter as a <code>java.sql.Date
+   * </code> object.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setDate
+   */
+  @Override
+  public Date getDate(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getDate(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>TIME</code> parameter as a <code>java.sql.Time
+   * </code> object.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setTime
+   */
+  @Override
+  public Time getTime(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getTime(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a <code>
+   * java.sql.Timestamp</code> object.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setTimestamp
+   */
+  @Override
+  public Timestamp getTimestamp(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getTimestamp(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated parameter as an <code>Object</code> in the Java
+   * programming language. If the value is an SQL <code>NULL</code>, the driver returns a Java
+   * <code>null</code>.
+   *
+   * <p>This method returns a Java object whose type corresponds to the JDBC type that was
+   * registered for this parameter using the method <code>registerOutParameter</code>. By
+   * registering the target JDBC types as <code>java.sql.Types.OTHER</code>, this method can be used
+   * to read database-specific abstract data types.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return A <code>java.lang.Object</code> holding the OUT parameter value
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see Types
+   * @see #setObject
+   */
+  @Override
+  public Object getObject(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getObject(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>NUMERIC</code> parameter as a <code>
+   * java.math.BigDecimal</code> object with as many digits to the right of the decimal point as the
+   * value contains.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value in full precision. If the value is SQL <code>NULL</code>, the
+   *     result is <code>null</code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setBigDecimal
+   * @since 1.2
+   */
+  @Override
+  public BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getBigDecimal(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Returns an object representing the value of OUT parameter <code>parameterIndex</code> and uses
+   * <code>map</code> for the custom mapping of the parameter value.
+   *
+   * <p>This method returns a Java object whose type corresponds to the JDBC type that was
+   * registered for this parameter using the method <code>registerOutParameter</code>. By
+   * registering the target JDBC types as <code>java.sql.Types.OTHER</code>, this method can be used
+   * to read database-specific abstract data types.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param map the mapping from SQL type names to Java classes
+   * @return a <code>java.lang.Object</code> holding the OUT parameter value
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setObject
+   * @since 1.2
+   */
+  @Override
+  public Object getObject(int parameterIndex, Map<String, Class<?>> map) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getObject(idxToOutIdx(parameterIndex), map);
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>REF(&lt;structured-type&gt;)</code> parameter
+   * as a {@link Ref} object in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value as a <code>Ref</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public Ref getRef(int parameterIndex) throws SQLException {
+    throw exceptionFactory().notSupported("Method ResultSet.getRef not supported");
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>BLOB</code> parameter as a {@link Blob} object
+   * in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value as a <code>Blob</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public Blob getBlob(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getBlob(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>CLOB</code> parameter as a <code>java.sql.Clob
+   * </code> object in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value as a <code>Clob</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public Clob getClob(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getClob(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>ARRAY</code> parameter as an {@link Array}
+   * object in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value as an <code>Array</code> object in the Java programming language.
+   *     If the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public Array getArray(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    throw exceptionFactory().notSupported("Method ResultSet.getArray not supported");
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>DATE</code> parameter as a <code>java.sql.Date
+   * </code> object, using the given <code>Calendar</code> object to construct the date. With a
+   * <code>Calendar</code> object, the driver can calculate the date taking into account a custom
+   * timezone and locale. If no <code>Calendar</code> object is specified, the driver uses the
+   * default timezone and locale.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param cal the <code>Calendar</code> object the driver will use to construct the date
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setDate
+   * @since 1.2
+   */
+  @Override
+  public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getDate(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>TIME</code> parameter as a <code>java.sql.Time
+   * </code> object, using the given <code>Calendar</code> object to construct the time. With a
+   * <code>Calendar</code> object, the driver can calculate the time taking into account a custom
+   * timezone and locale. If no <code>Calendar</code> object is specified, the driver uses the
+   * default timezone and locale.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param cal the <code>Calendar</code> object the driver will use to construct the time
+   * @return the parameter value; if the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setTime
+   * @since 1.2
+   */
+  @Override
+  public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getTime(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>TIMESTAMP</code> parameter as a <code>
+   * java.sql.Timestamp</code> object, using the given <code>Calendar</code> object to construct the
+   * <code>Timestamp</code> object. With a <code>Calendar</code> object, the driver can calculate
+   * the timestamp taking into account a custom timezone and locale. If no <code>Calendar</code>
+   * object is specified, the driver uses the default timezone and locale.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param cal the <code>Calendar</code> object the driver will use to construct the timestamp
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @see #setTimestamp
+   * @since 1.2
+   */
+  @Override
+  public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getTimestamp(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Registers the designated output parameter. This version of the method <code>
+   * registerOutParameter</code> should be used for a user-defined or <code>REF</code> output
+   * parameter. Examples of user-defined types include: <code>STRUCT</code>, <code>DISTINCT</code>,
+   * <code>JAVA_OBJECT</code>, and named array types.
+   *
+   * <p>All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>For a user-defined parameter, the fully-qualified SQL type name of the parameter should also
+   * be given, while a <code>REF</code> parameter requires that the fully-qualified type name of the
+   * referenced type be given. A JDBC driver that does not need the type code and type name
+   * information may ignore it. To be portable, however, applications should always provide these
+   * values for user-defined and <code>REF</code> parameters.
+   *
+   * <p>Although it is intended for user-defined and <code>REF</code> parameters, this method may be
+   * used to register a parameter of any JDBC type. If the parameter does not have a user-defined or
+   * <code>REF</code> type, the <i>typeName</i> parameter is ignored.
+   *
+   * <p><B>Note:</B> When reading the value of an out parameter, you must use the getter method
+   * whose Java type corresponds to the parameter's registered SQL type.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2,...
+   * @param sqlType a value from {@link Types}
+   * @param typeName the fully-qualified name of an SQL structured type
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type
+   * @see Types
+   * @since 1.2
+   */
+  @Override
+  public void registerOutParameter(int parameterIndex, int sqlType, String typeName)
+      throws SQLException {
+    registerOutParameter(parameterIndex, sqlType);
+  }
+
+  /**
+   * Registers the OUT parameter named <code>parameterName</code> to the JDBC type <code>sqlType
+   * </code>. All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>The JDBC type specified by <code>sqlType</code> for an OUT parameter determines the Java
+   * type that must be used in the <code>get</code> method to read the value of that parameter.
+   *
+   * <p>If the JDBC type expected to be returned to this output parameter is specific to this
+   * particular database, <code>sqlType</code> should be <code>java.sql.Types.OTHER</code>. The
+   * method {@link #getObject} retrieves the value.
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType the JDBC type code defined by <code>java.sql.Types</code>. If the parameter is
+   *     of JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>, the version of <code>
+   *     registerOutParameter</code> that accepts a scale value should be used.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type or if the JDBC driver does not support this
+   *     method
+   * @see Types
+   * @since 1.4
+   */
+  @Override
+  public void registerOutParameter(String parameterName, int sqlType) throws SQLException {
+    checkNotClosed();
+    registerOutParameter(nameToIndex(parameterName), sqlType);
+  }
+
+  private int nameToIndex(String parameterName) throws SQLException {
+    if (parameterName == null) throw exceptionFactory().create("parameter name cannot be null");
+    if (parameterMetaData == null) parameterMetaData = getParameterMetaData();
+
+    int count = parameterMetaData.getParameterCount();
+    for (int i = 1; i <= count; i++) {
+      String name = parameterMetaData.getParameterName(i);
+      if (name != null && name.equalsIgnoreCase(parameterName)) {
+        return i;
+      }
+    }
+    throw exceptionFactory().create(String.format("parameter name %s not found", parameterName));
+  }
+
+  /**
+   * Registers the parameter named <code>parameterName</code> to be of JDBC type <code>sqlType
+   * </code>. All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>The JDBC type specified by <code>sqlType</code> for an OUT parameter determines the Java
+   * type that must be used in the <code>get</code> method to read the value of that parameter.
+   *
+   * <p>This version of <code>registerOutParameter</code> should be used when the parameter is of
+   * JDBC type <code>NUMERIC</code> or <code>DECIMAL</code>.
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType SQL type code defined by <code>java.sql.Types</code>.
+   * @param scale the desired number of digits to the right of the decimal point. It must be greater
+   *     than or equal to zero.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type or if the JDBC driver does not support this
+   *     method
+   * @see Types
+   * @since 1.4
+   */
+  @Override
+  public void registerOutParameter(String parameterName, int sqlType, int scale)
+      throws SQLException {
+    registerOutParameter(parameterName, sqlType);
+  }
+
+  /**
+   * Registers the designated output parameter. This version of the method <code>
+   * registerOutParameter</code> should be used for a user-named or REF output parameter. Examples
+   * of user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and named array types.
+   *
+   * <p>All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>For a user-named parameter the fully-qualified SQL type name of the parameter should also be
+   * given, while a REF parameter requires that the fully-qualified type name of the referenced type
+   * be given. A JDBC driver that does not need the type code and type name information may ignore
+   * it. To be portable, however, applications should always provide these values for user-named and
+   * REF parameters.
+   *
+   * <p>Although it is intended for user-named and REF parameters, this method may be used to
+   * register a parameter of any JDBC type. If the parameter does not have a user-named or REF type,
+   * the typeName parameter is ignored.
+   *
+   * <p><B>Note:</B> When reading the value of an out parameter, you must use the <code>getXXX
+   * </code> method whose Java type XXX corresponds to the parameter's registered SQL type.
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType a value from {@link Types}
+   * @param typeName the fully-qualified name of an SQL structured type
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type or if the JDBC driver does not support this
+   *     method
+   * @see Types
+   * @since 1.4
+   */
+  @Override
+  public void registerOutParameter(String parameterName, int sqlType, String typeName)
+      throws SQLException {
+    registerOutParameter(parameterName, sqlType);
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>DATALINK</code> parameter as a <code>
+   * java.net.URL</code> object.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2,...
+   * @return a <code>java.net.URL</code> object that represents the JDBC <code>DATALINK</code> value
+   *     used as the designated parameter
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs,
+   *     this method is called on a closed <code>CallableStatement</code>, or if the URL being
+   *     returned is not a valid URL on the Java platform
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setURL
+   * @since 1.4
+   */
+  @Override
+  public URL getURL(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getURL(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.net.URL</code> object. The driver
+   * converts this to an SQL <code>DATALINK</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param val the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs; this method is called on a closed <code>CallableStatement</code> or if
+   *     a URL is malformed
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getURL
+   * @since 1.4
+   */
+  @Override
+  public void setURL(String parameterName, URL val) throws SQLException {
+    setURL(nameToIndex(parameterName), val);
+  }
+
+  /**
+   * Sets the designated parameter to SQL <code>NULL</code>.
+   *
+   * <p><B>Note:</B> You must specify the parameter's SQL type.
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType the SQL type code defined in <code>java.sql.Types</code>
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public void setNull(String parameterName, int sqlType) throws SQLException {
+    setNull(nameToIndex(parameterName), sqlType);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>boolean</code> value. The driver converts
+   * this to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getBoolean
+   * @since 1.4
+   */
+  @Override
+  public void setBoolean(String parameterName, boolean x) throws SQLException {
+    setBoolean(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>byte</code> value. The driver converts
+   * this to an SQL <code>TINYINT</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getByte
+   * @since 1.4
+   */
+  @Override
+  public void setByte(String parameterName, byte x) throws SQLException {
+    setByte(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>short</code> value. The driver converts
+   * this to an SQL <code>SMALLINT</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getShort
+   * @since 1.4
+   */
+  @Override
+  public void setShort(String parameterName, short x) throws SQLException {
+    setShort(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>int</code> value. The driver converts
+   * this to an SQL <code>INTEGER</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getInt
+   * @since 1.4
+   */
+  @Override
+  public void setInt(String parameterName, int x) throws SQLException {
+    setInt(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>long</code> value. The driver converts
+   * this to an SQL <code>BIGINT</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getLong
+   * @since 1.4
+   */
+  @Override
+  public void setLong(String parameterName, long x) throws SQLException {
+    setLong(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>float</code> value. The driver converts
+   * this to an SQL <code>FLOAT</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getFloat
+   * @since 1.4
+   */
+  @Override
+  public void setFloat(String parameterName, float x) throws SQLException {
+    setFloat(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>double</code> value. The driver converts
+   * this to an SQL <code>DOUBLE</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getDouble
+   * @since 1.4
+   */
+  @Override
+  public void setDouble(String parameterName, double x) throws SQLException {
+    setDouble(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.math.BigDecimal</code> value. The driver
+   * converts this to an SQL <code>NUMERIC</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getBigDecimal
+   * @since 1.4
+   */
+  @Override
+  public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
+    setBigDecimal(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>String</code> value. The driver converts
+   * this to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value (depending on the
+   * argument's size relative to the driver's limits on <code>VARCHAR</code> values) when it sends
+   * it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getString
+   * @since 1.4
+   */
+  @Override
+  public void setString(String parameterName, String x) throws SQLException {
+    setString(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java array of bytes. The driver converts this to an
+   * SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code> (depending on the argument's size
+   * relative to the driver's limits on <code>VARBINARY</code> values) when it sends it to the
+   * database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getBytes
+   * @since 1.4
+   */
+  @Override
+  public void setBytes(String parameterName, byte[] x) throws SQLException {
+    setBytes(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Date</code> value using the default
+   * time zone of the virtual machine that is running the application. The driver converts this to
+   * an SQL <code>DATE</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getDate
+   * @since 1.4
+   */
+  @Override
+  public void setDate(String parameterName, Date x) throws SQLException {
+    setDate(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Time</code> value. The driver
+   * converts this to an SQL <code>TIME</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getTime
+   * @since 1.4
+   */
+  @Override
+  public void setTime(String parameterName, Time x) throws SQLException {
+    setTime(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value. The driver
+   * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getTimestamp
+   * @since 1.4
+   */
+  @Override
+  public void setTimestamp(String parameterName, Timestamp x) throws SQLException {
+    setTimestamp(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large ASCII value is input to a <code>LONGVARCHAR</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code>. Data will be read from
+   * the stream as needed until end-of-file is reached. The JDBC driver will do any necessary
+   * conversion from ASCII to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the Java input stream that contains the ASCII parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException {
+    setAsciiStream(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large binary value is input to a <code>LONGVARBINARY</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code> object. The data will
+   * be read from the stream as needed until end-of-file is reached.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the java input stream which contains the binary parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException {
+    setBinaryStream(nameToIndex(parameterName), x, length);
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>The given Java object will be converted to the given targetSqlType before being sent to the
+   * database.
+   *
+   * <p>If the object has a custom mapping (is of a class implementing the interface <code>SQLData
+   * </code>), the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it to
+   * the SQL data stream. If, on the other hand, the object is of a class implementing <code>Ref
+   * </code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, <code>Struct</code>, <code>
+   * java.net.URL</code>, or <code>Array</code>, the driver should pass it to the database as a
+   * value of the corresponding SQL type.
+   *
+   * <p>Note that this method may be used to pass datatabase- specific abstract data types.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent to the database.
+   *     The scale argument may further qualify this type.
+   * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, this is the number of
+   *     digits after the decimal point. For all other types, this value will be ignored.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see Types
+   * @see #getObject
+   * @since 1.4
+   */
+  @Override
+  public void setObject(String parameterName, Object x, int targetSqlType, int scale)
+      throws SQLException {
+    setObject(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>This method is similar to {@link #setObject(String parameterName, Object x, int
+   * targetSqlType, int scaleOrLength)}, except that it assumes a scale of zero.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent to the database
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see #getObject
+   * @since 1.4
+   */
+  @Override
+  public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException {
+    setObject(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>The JDBC specification specifies a standard mapping from Java <code>Object</code> types to
+   * SQL types. The given argument will be converted to the corresponding SQL type before being sent
+   * to the database.
+   *
+   * <p>Note that this method may be used to pass database- specific abstract data types, by using a
+   * driver-specific Java type.
+   *
+   * <p>If the object is of a class implementing the interface <code>SQLData</code>, the JDBC driver
+   * should call the method <code>SQLData.writeSQL</code> to write it to the SQL data stream. If, on
+   * the other hand, the object is of a class implementing <code>Ref</code>, <code>Blob</code>,
+   * <code>Clob</code>, <code>NClob</code>, <code>Struct</code>, <code>java.net.URL</code>, or
+   * <code>Array</code>, the driver should pass it to the database as a value of the corresponding
+   * SQL type.
+   *
+   * <p>This method throws an exception if there is an ambiguity, for example, if the object is of a
+   * class implementing more than one of the interfaces named above.
+   *
+   * <p><b>Note:</b> Not all databases allow for a non-typed Null to be sent to the backend. For
+   * maximum portability, the <code>setNull</code> or the <code>
+   * setObject(String parameterName, Object x, int sqlType)</code> method should be used instead of
+   * <code>setObject(String parameterName, Object x)</code>.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the object containing the input parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs, this method is called on a closed <code>CallableStatement</code> or if
+   *     the given <code>Object</code> parameter is ambiguous
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getObject
+   * @since 1.4
+   */
+  @Override
+  public void setObject(String parameterName, Object x) throws SQLException {
+    setObject(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>Reader</code> object, which is the given
+   * number of characters long. When a very large UNICODE value is input to a <code>LONGVARCHAR
+   * </code> parameter, it may be more practical to send it via a <code>java.io.Reader</code>
+   * object. The data will be read from the stream as needed until end-of-file is reached. The JDBC
+   * driver will do any necessary conversion from UNICODE to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterName the name of the parameter
+   * @param reader the <code>java.io.Reader</code> object that contains the UNICODE data used as the
+   *     designated parameter
+   * @param length the number of characters in the stream
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public void setCharacterStream(String parameterName, Reader reader, int length)
+      throws SQLException {
+    setCharacterStream(nameToIndex(parameterName), reader, length);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Date</code> value, using the given
+   * <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to construct an
+   * SQL <code>DATE</code> value, which the driver then sends to the database. With a a <code>
+   * Calendar</code> object, the driver can calculate the date taking into account a custom
+   * timezone. If no <code>Calendar</code> object is specified, the driver uses the default
+   * timezone, which is that of the virtual machine running the application.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @param cal the <code>Calendar</code> object the driver will use to construct the date
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getDate
+   * @since 1.4
+   */
+  @Override
+  public void setDate(String parameterName, Date x, Calendar cal) throws SQLException {
+    setDate(nameToIndex(parameterName), x, cal);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Time</code> value, using the given
+   * <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to construct an
+   * SQL <code>TIME</code> value, which the driver then sends to the database. With a a <code>
+   * Calendar</code> object, the driver can calculate the time taking into account a custom
+   * timezone. If no <code>Calendar</code> object is specified, the driver uses the default
+   * timezone, which is that of the virtual machine running the application.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @param cal the <code>Calendar</code> object the driver will use to construct the time
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getTime
+   * @since 1.4
+   */
+  @Override
+  public void setTime(String parameterName, Time x, Calendar cal) throws SQLException {
+    setTime(nameToIndex(parameterName), x, cal);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value, using the
+   * given <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to
+   * construct an SQL <code>TIMESTAMP</code> value, which the driver then sends to the database.
+   * With a a <code>Calendar</code> object, the driver can calculate the timestamp taking into
+   * account a custom timezone. If no <code>Calendar</code> object is specified, the driver uses the
+   * default timezone, which is that of the virtual machine running the application.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @param cal the <code>Calendar</code> object the driver will use to construct the timestamp
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #getTimestamp
+   * @since 1.4
+   */
+  @Override
+  public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException {
+    setTimestamp(nameToIndex(parameterName), x, cal);
+  }
+
+  /**
+   * Sets the designated parameter to SQL <code>NULL</code>. This version of the method <code>
+   * setNull</code> should be used for user-defined types and REF type parameters. Examples of
+   * user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and named array types.
+   *
+   * <p><B>Note:</B> To be portable, applications must give the SQL type code and the
+   * fully-qualified SQL type name when specifying a NULL user-defined or REF parameter. In the case
+   * of a user-defined type the name is the type name of the parameter itself. For a REF parameter,
+   * the name is the type name of the referenced type.
+   *
+   * <p>Although it is intended for user-defined and Ref parameters, this method may be used to set
+   * a null parameter of any JDBC type. If the parameter does not have a user-defined or REF type,
+   * the given typeName is ignored.
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType a value from <code>java.sql.Types</code>
+   * @param typeName the fully-qualified name of an SQL user-defined type; ignored if the parameter
+   *     is not a user-defined type or SQL <code>REF</code> value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public void setNull(String parameterName, int sqlType, String typeName) throws SQLException {
+    setNull(nameToIndex(parameterName), sqlType, typeName);
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>, or <code>LONGVARCHAR
+   * </code> parameter as a <code>String</code> in the Java programming language.
+   *
+   * <p>For the fixed-length type JDBC <code>CHAR</code>, the <code>String</code> object returned
+   * has exactly the same value the SQL <code>CHAR</code> value had in the database, including any
+   * padding added by the database.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setString
+   * @since 1.4
+   */
+  @Override
+  public String getString(String parameterName) throws SQLException {
+    return outputResult.getString(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>BIT</code> or <code>BOOLEAN</code> parameter as a <code>
+   * boolean</code> in the Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>false
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setBoolean
+   * @since 1.4
+   */
+  @Override
+  public boolean getBoolean(String parameterName) throws SQLException {
+    return outputResult.getBoolean(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code> in the Java
+   * programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setByte
+   * @since 1.4
+   */
+  @Override
+  public byte getByte(String parameterName) throws SQLException {
+    return outputResult.getByte(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code> in the
+   * Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setShort
+   * @since 1.4
+   */
+  @Override
+  public short getShort(String parameterName) throws SQLException {
+    return outputResult.getShort(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code> in the Java
+   * programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setInt
+   * @since 1.4
+   */
+  @Override
+  public int getInt(String parameterName) throws SQLException {
+    return outputResult.getInt(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code> in the Java
+   * programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setLong
+   * @since 1.4
+   */
+  @Override
+  public long getLong(String parameterName) throws SQLException {
+    return outputResult.getLong(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code> in the Java
+   * programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setFloat
+   * @since 1.4
+   */
+  @Override
+  public float getFloat(String parameterName) throws SQLException {
+    return outputResult.getFloat(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code> in the
+   * Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>0
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setDouble
+   * @since 1.4
+   */
+  @Override
+  public double getDouble(String parameterName) throws SQLException {
+    return outputResult.getDouble(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code> parameter as an
+   * array of <code>byte</code> values in the Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setBytes
+   * @since 1.4
+   */
+  @Override
+  public byte[] getBytes(String parameterName) throws SQLException {
+    return outputResult.getBytes(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>DATE</code> parameter as a <code>java.sql.Date</code>
+   * object.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setDate
+   * @since 1.4
+   */
+  @Override
+  public Date getDate(String parameterName) throws SQLException {
+    return outputResult.getDate(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>TIME</code> parameter as a <code>java.sql.Time</code>
+   * object.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setTime
+   * @since 1.4
+   */
+  @Override
+  public Time getTime(String parameterName) throws SQLException {
+    return outputResult.getTime(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a <code>java.sql.Timestamp
+   * </code> object.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setTimestamp
+   * @since 1.4
+   */
+  @Override
+  public Timestamp getTimestamp(String parameterName) throws SQLException {
+    return outputResult.getTimestamp(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a parameter as an <code>Object</code> in the Java programming language.
+   * If the value is an SQL <code>NULL</code>, the driver returns a Java <code>null</code>.
+   *
+   * <p>This method returns a Java object whose type corresponds to the JDBC type that was
+   * registered for this parameter using the method <code>registerOutParameter</code>. By
+   * registering the target JDBC types as <code>java.sql.Types.OTHER</code>, this method can be used
+   * to read database-specific abstract data types.
+   *
+   * @param parameterName the name of the parameter
+   * @return A <code>java.lang.Object</code> holding the OUT parameter value.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see Types
+   * @see #setObject
+   * @since 1.4
+   */
+  @Override
+  public Object getObject(String parameterName) throws SQLException {
+    return outputResult.getObject(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>NUMERIC</code> parameter as a <code>java.math.BigDecimal
+   * </code> object with as many digits to the right of the decimal point as the value contains.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value in full precision. If the value is SQL <code>NULL</code>, the
+   *     result is <code>null</code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setBigDecimal
+   * @since 1.4
+   */
+  @Override
+  public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+    return outputResult.getBigDecimal(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Returns an object representing the value of OUT parameter <code>parameterName</code> and uses
+   * <code>map</code> for the custom mapping of the parameter value.
+   *
+   * <p>This method returns a Java object whose type corresponds to the JDBC type that was
+   * registered for this parameter using the method <code>registerOutParameter</code>. By
+   * registering the target JDBC types as <code>java.sql.Types.OTHER</code>, this method can be used
+   * to read database-specific abstract data types.
+   *
+   * @param parameterName the name of the parameter
+   * @param map the mapping from SQL type names to Java classes
+   * @return a <code>java.lang.Object</code> holding the OUT parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setObject
+   * @since 1.4
+   */
+  @Override
+  public Object getObject(String parameterName, Map<String, Class<?>> map) throws SQLException {
+    return outputResult.getObject(idxToOutIdx(nameToIndex(parameterName)), map);
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>REF(&lt;structured-type&gt;)</code> parameter as a {@link
+   * Ref} object in the Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value as a <code>Ref</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public Ref getRef(String parameterName) throws SQLException {
+    throw exceptionFactory().notSupported("Method ResultSet.getRef not supported");
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>BLOB</code> parameter as a {@link Blob} object in the Java
+   * programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value as a <code>Blob</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public Blob getBlob(String parameterName) throws SQLException {
+    return outputResult.getBlob(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>CLOB</code> parameter as a <code>java.sql.Clob</code>
+   * object in the Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value as a <code>Clob</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public Clob getClob(String parameterName) throws SQLException {
+    return outputResult.getClob(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>ARRAY</code> parameter as an {@link Array} object in the
+   * Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value as an <code>Array</code> object in Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public Array getArray(String parameterName) throws SQLException {
+    throw exceptionFactory().notSupported("Method ResultSet.getArray not supported");
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>DATE</code> parameter as a <code>java.sql.Date</code>
+   * object, using the given <code>Calendar</code> object to construct the date. With a <code>
+   * Calendar</code> object, the driver can calculate the date taking into account a custom timezone
+   * and locale. If no <code>Calendar</code> object is specified, the driver uses the default
+   * timezone and locale.
+   *
+   * @param parameterName the name of the parameter
+   * @param cal the <code>Calendar</code> object the driver will use to construct the date
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setDate
+   * @since 1.4
+   */
+  @Override
+  public Date getDate(String parameterName, Calendar cal) throws SQLException {
+    return outputResult.getDate(idxToOutIdx(nameToIndex(parameterName)), cal);
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>TIME</code> parameter as a <code>java.sql.Time</code>
+   * object, using the given <code>Calendar</code> object to construct the time. With a <code>
+   * Calendar</code> object, the driver can calculate the time taking into account a custom timezone
+   * and locale. If no <code>Calendar</code> object is specified, the driver uses the default
+   * timezone and locale.
+   *
+   * @param parameterName the name of the parameter
+   * @param cal the <code>Calendar</code> object the driver will use to construct the time
+   * @return the parameter value; if the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setTime
+   * @since 1.4
+   */
+  @Override
+  public Time getTime(String parameterName, Calendar cal) throws SQLException {
+    return outputResult.getTime(idxToOutIdx(nameToIndex(parameterName)), cal);
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>TIMESTAMP</code> parameter as a <code>java.sql.Timestamp
+   * </code> object, using the given <code>Calendar</code> object to construct the <code>Timestamp
+   * </code> object. With a <code>Calendar</code> object, the driver can calculate the timestamp
+   * taking into account a custom timezone and locale. If no <code>Calendar</code> object is
+   * specified, the driver uses the default timezone and locale.
+   *
+   * @param parameterName the name of the parameter
+   * @param cal the <code>Calendar</code> object the driver will use to construct the timestamp
+   * @return the parameter value. If the value is SQL <code>NULL</code>, the result is <code>null
+   *     </code>.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setTimestamp
+   * @since 1.4
+   */
+  @Override
+  public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException {
+    return outputResult.getTimestamp(idxToOutIdx(nameToIndex(parameterName)), cal);
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>DATALINK</code> parameter as a <code>java.net.URL</code>
+   * object.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value as a <code>java.net.URL</code> object in the Java programming
+   *     language. If the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs, this method is called on a closed <code>CallableStatement</code>, or
+   *     if there is a problem with the URL
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setURL
+   * @since 1.4
+   */
+  @Override
+  public URL getURL(String parameterName) throws SQLException {
+    return outputResult.getURL(idxToOutIdx(nameToIndex(parameterName)));
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a <code>
+   * java.sql.RowId</code> object.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2,...
+   * @return a <code>RowId</code> object that represents the JDBC <code>ROWID</code> value is used
+   *     as the designated parameter. If the parameter contains an SQL <code>NULL</code>, then a
+   *     <code>null</code> value is returned.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public RowId getRowId(int parameterIndex) throws SQLException {
+    throw exceptionFactory().notSupported("RowId are not supported");
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>ROWID</code> parameter as a <code>
+   * java.sql.RowId</code> object.
+   *
+   * @param parameterName the name of the parameter
+   * @return a <code>RowId</code> object that represents the JDBC <code>ROWID</code> value is used
+   *     as the designated parameter. If the parameter contains an SQL <code>NULL</code>, then a
+   *     <code>null</code> value is returned.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public RowId getRowId(String parameterName) throws SQLException {
+    throw exceptionFactory().notSupported("RowId are not supported");
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The driver
+   * converts this to an SQL <code>ROWID</code> when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setRowId(String parameterName, RowId x) throws SQLException {
+    throw exceptionFactory().notSupported("RowId parameter are not supported");
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>String</code> object. The driver converts this
+   * to an SQL <code>NCHAR</code> or <code>NVARCHAR</code> or <code>LONGNVARCHAR</code>
+   *
+   * @param parameterName the name of the parameter to be set
+   * @param value the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the driver
+   *     does not support national character sets; if the driver can detect that a data conversion
+   *     error could occur; if a database access error occurs or this method is called on a closed
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNString(String parameterName, String value) throws SQLException {
+    setNString(nameToIndex(parameterName), value);
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The <code>Reader</code> reads
+   * the data till end-of-file is reached. The driver does the necessary conversion from Java
+   * character format to the national character set in the database.
+   *
+   * @param parameterName the name of the parameter to be set
+   * @param value the parameter value
+   * @param length the number of characters in the parameter data.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the driver
+   *     does not support national character sets; if the driver can detect that a data conversion
+   *     error could occur; if a database access error occurs or this method is called on a closed
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNCharacterStream(String parameterName, Reader value, long length)
+      throws SQLException {
+    setNCharacterStream(nameToIndex(parameterName), value, length);
+  }
+
+  /**
+   * Sets the designated parameter to a <code>java.sql.NClob</code> object. The object implements
+   * the <code>java.sql.NClob</code> interface. This <code>NClob</code> object maps to an SQL <code>
+   * NCLOB</code>.
+   *
+   * @param parameterName the name of the parameter to be set
+   * @param value the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the driver
+   *     does not support national character sets; if the driver can detect that a data conversion
+   *     error could occur; if a database access error occurs or this method is called on a closed
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNClob(String parameterName, NClob value) throws SQLException {
+    setNClob(nameToIndex(parameterName), value);
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must
+   * contain the number of characters specified by length otherwise a <code>SQLException</code> will
+   * be generated when the <code>CallableStatement</code> is executed. This method differs from the
+   * <code>setCharacterStream (int, Reader, int)</code> method because it informs the driver that
+   * the parameter value should be sent to the server as a <code>CLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGVARCHAR</code> or a
+   * <code>CLOB</code>
+   *
+   * @param parameterName the name of the parameter to be set
+   * @param reader An object that contains the data to set the parameter value to.
+   * @param length the number of characters in the parameter data.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the length
+   *     specified is less than zero; a database access error occurs or this method is called on a
+   *     closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setClob(String parameterName, Reader reader, long length) throws SQLException {
+    setClob(nameToIndex(parameterName), reader, length);
+  }
+
+  /**
+   * Sets the designated parameter to an {@code InputStream} object. The <code>Inputstream</code>
+   * must contain the number of characters specified by length, otherwise a <code>SQLException
+   * </code> will be generated when the <code>CallableStatement</code> is executed. This method
+   * differs from the <code>setBinaryStream (int, InputStream, int)</code> method because it informs
+   * the driver that the parameter value should be sent to the server as a <code>BLOB</code>. When
+   * the <code>setBinaryStream</code> method is used, the driver may have to do extra work to
+   * determine whether the parameter data should be sent to the server as a <code>LONGVARBINARY
+   * </code> or a <code>BLOB</code>
+   *
+   * @param parameterName the name of the parameter to be set the second is 2, ...
+   * @param inputStream An object that contains the data to set the parameter value to.
+   * @param length the number of bytes in the parameter data.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the length
+   *     specified is less than zero; if the number of bytes in the {@code InputStream} does not
+   *     match the specified length; if a database access error occurs or this method is called on a
+   *     closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBlob(String parameterName, InputStream inputStream, long length)
+      throws SQLException {
+    setBlob(nameToIndex(parameterName), inputStream, length);
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must
+   * contain the number of characters specified by length otherwise a <code>SQLException</code> will
+   * be generated when the <code>CallableStatement</code> is executed. This method differs from the
+   * <code>setCharacterStream (int, Reader, int)</code> method because it informs the driver that
+   * the parameter value should be sent to the server as a <code>NCLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGNVARCHAR</code> or a
+   * <code>NCLOB</code>
+   *
+   * @param parameterName the name of the parameter to be set
+   * @param reader An object that contains the data to set the parameter value to.
+   * @param length the number of characters in the parameter data.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the length
+   *     specified is less than zero; if the driver does not support national character sets; if the
+   *     driver can detect that a data conversion error could occur; if a database access error
+   *     occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
+    setNClob(nameToIndex(parameterName), reader, length);
+  }
+
+  /**
+   * Retrieves the value of the designated JDBC <code>NCLOB</code> parameter as a <code>
+   * java.sql.NClob</code> object in the Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @return the parameter value as a <code>NClob</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if the parameterIndex is not valid; if the driver does not support
+   *     national character sets; if the driver can detect that a data conversion error could occur;
+   *     if a database access error occurs or this method is called on a closed <code>
+   *     CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public NClob getNClob(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getNClob(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of a JDBC <code>NCLOB</code> parameter as a <code>java.sql.NClob</code>
+   * object in the Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return the parameter value as a <code>NClob</code> object in the Java programming language. If
+   *     the value was SQL <code>NULL</code>, the value <code>null</code> is returned.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the driver
+   *     does not support national character sets; if the driver can detect that a data conversion
+   *     error could occur; if a database access error occurs or this method is called on a closed
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public NClob getNClob(String parameterName) throws SQLException {
+    return getNClob(nameToIndex(parameterName));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver
+   * converts this to an <code>SQL XML</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param xmlObject a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs; this method is called on a closed <code>CallableStatement</code> or
+   *     the <code>java.xml.transform.Result</code>, <code>Writer</code> or <code>OutputStream
+   *     </code> has not been closed for the <code>SQLXML</code> object
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {
+    throw exceptionFactory().notSupported("SQLXML parameter are not supported");
+  }
+
+  /**
+   * Retrieves the value of the designated <code>SQL XML</code> parameter as a <code>java.sql.SQLXML
+   * </code> object in the Java programming language.
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+    throw exceptionFactory().notSupported("SQLXML are not supported");
+  }
+
+  /**
+   * Retrieves the value of the designated <code>SQL XML</code> parameter as a <code>java.sql.SQLXML
+   * </code> object in the Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return a <code>SQLXML</code> object that maps an <code>SQL XML</code> value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public SQLXML getSQLXML(String parameterName) throws SQLException {
+    throw exceptionFactory().notSupported("SQLXML are not supported");
+  }
+
+  private ExceptionFactory exceptionFactory() {
+    return con.getExceptionFactory().of(this);
+  }
+
+  /**
+   * Retrieves the value of the designated <code>NCHAR</code>, <code>NVARCHAR</code> or <code>
+   * LONGNVARCHAR</code> parameter as a <code>String</code> in the Java programming language.
+   *
+   * <p>For the fixed-length type JDBC <code>NCHAR</code>, the <code>String</code> object returned
+   * has exactly the same value the SQL <code>NCHAR</code> value had in the database, including any
+   * padding added by the database.
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @return a <code>String</code> object that maps an <code>NCHAR</code>, <code>NVARCHAR</code> or
+   *     <code>LONGNVARCHAR</code> value
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setNString
+   * @since 1.6
+   */
+  @Override
+  public String getNString(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getNString(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated <code>NCHAR</code>, <code>NVARCHAR</code> or <code>
+   * LONGNVARCHAR</code> parameter as a <code>String</code> in the Java programming language.
+   *
+   * <p>For the fixed-length type JDBC <code>NCHAR</code>, the <code>String</code> object returned
+   * has exactly the same value the SQL <code>NCHAR</code> value had in the database, including any
+   * padding added by the database.
+   *
+   * @param parameterName the name of the parameter
+   * @return a <code>String</code> object that maps an <code>NCHAR</code>, <code>NVARCHAR</code> or
+   *     <code>LONGNVARCHAR</code> value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @see #setNString
+   * @since 1.6
+   */
+  @Override
+  public String getNString(String parameterName) throws SQLException {
+    return getNString(nameToIndex(parameterName));
+  }
+
+  /**
+   * Retrieves the value of the designated parameter as a <code>java.io.Reader</code> object in the
+   * Java programming language. It is intended for use when accessing <code>NCHAR</code>,<code>
+   * NVARCHAR</code> and <code>LONGNVARCHAR</code> parameters.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @return a <code>java.io.Reader</code> object that contains the parameter value; if the value is
+   *     SQL <code>NULL</code>, the value returned is <code>null</code> in the Java programming
+   *     language.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getNCharacterStream(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated parameter as a <code>java.io.Reader</code> object in the
+   * Java programming language. It is intended for use when accessing <code>NCHAR</code>,<code>
+   * NVARCHAR</code> and <code>LONGNVARCHAR</code> parameters.
+   *
+   * @param parameterName the name of the parameter
+   * @return a <code>java.io.Reader</code> object that contains the parameter value; if the value is
+   *     SQL <code>NULL</code>, the value returned is <code>null</code> in the Java programming
+   *     language
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public Reader getNCharacterStream(String parameterName) throws SQLException {
+    return getNCharacterStream(nameToIndex(parameterName));
+  }
+
+  /**
+   * Retrieves the value of the designated parameter as a <code>java.io.Reader</code> object in the
+   * Java programming language.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @return a <code>java.io.Reader</code> object that contains the parameter value; if the value is
+   *     SQL <code>NULL</code>, the value returned is <code>null</code> in the Java programming
+   *     language.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed <code>CallableStatement</code>
+   * @since 1.6
+   */
+  @Override
+  public Reader getCharacterStream(int parameterIndex) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getCharacterStream(idxToOutIdx(parameterIndex));
+  }
+
+  /**
+   * Retrieves the value of the designated parameter as a <code>java.io.Reader</code> object in the
+   * Java programming language.
+   *
+   * @param parameterName the name of the parameter
+   * @return a <code>java.io.Reader</code> object that contains the parameter value; if the value is
+   *     SQL <code>NULL</code>, the value returned is <code>null</code> in the Java programming
+   *     language
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public Reader getCharacterStream(String parameterName) throws SQLException {
+    return getNCharacterStream(nameToIndex(parameterName));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Blob</code> object. The driver
+   * converts this to an SQL <code>BLOB</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBlob(String parameterName, Blob x) throws SQLException {
+    setBlob(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Clob</code> object. The driver
+   * converts this to an SQL <code>CLOB</code> value when it sends it to the database.
+   *
+   * @param parameterName the name of the parameter
+   * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setClob(String parameterName, Clob x) throws SQLException {
+    setClob(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large ASCII value is input to a <code>LONGVARCHAR</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code>. Data will be read from
+   * the stream as needed until end-of-file is reached. The JDBC driver will do any necessary
+   * conversion from ASCII to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the Java input stream that contains the ASCII parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
+    setAsciiStream(nameToIndex(parameterName), x, length);
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large binary value is input to a <code>LONGVARBINARY</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code> object. The data will
+   * be read from the stream as needed until end-of-file is reached.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the java input stream which contains the binary parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBinaryStream(String parameterName, InputStream x, long length)
+      throws SQLException {
+    setBinaryStream(nameToIndex(parameterName), x, length);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>Reader</code> object, which is the given
+   * number of characters long. When a very large UNICODE value is input to a <code>LONGVARCHAR
+   * </code> parameter, it may be more practical to send it via a <code>java.io.Reader</code>
+   * object. The data will be read from the stream as needed until end-of-file is reached. The JDBC
+   * driver will do any necessary conversion from UNICODE to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterName the name of the parameter
+   * @param reader the <code>java.io.Reader</code> object that contains the UNICODE data used as the
+   *     designated parameter
+   * @param length the number of characters in the stream
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setCharacterStream(String parameterName, Reader reader, long length)
+      throws SQLException {
+    setCharacterStream(nameToIndex(parameterName), reader, length);
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream. When a very large ASCII value is input
+   * to a <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a <code>
+   * java.io.InputStream</code>. Data will be read from the stream as needed until end-of-file is
+   * reached. The JDBC driver will do any necessary conversion from ASCII to the database char
+   * format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setAsciiStream</code> which takes a length parameter.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the Java input stream that contains the ASCII parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
+    setAsciiStream(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream. When a very large binary value is
+   * input to a <code>LONGVARBINARY</code> parameter, it may be more practical to send it via a
+   * <code>java.io.InputStream</code> object. The data will be read from the stream as needed until
+   * end-of-file is reached.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setBinaryStream</code> which takes a length parameter.
+   *
+   * @param parameterName the name of the parameter
+   * @param x the java input stream which contains the binary parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
+    setBinaryStream(nameToIndex(parameterName), x);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>Reader</code> object. When a very large
+   * UNICODE value is input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+   * send it via a <code>java.io.Reader</code> object. The data will be read from the stream as
+   * needed until end-of-file is reached. The JDBC driver will do any necessary conversion from
+   * UNICODE to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setCharacterStream</code> which takes a length parameter.
+   *
+   * @param parameterName the name of the parameter
+   * @param reader the <code>java.io.Reader</code> object that contains the Unicode data
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
+    setCharacterStream(nameToIndex(parameterName), reader);
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The <code>Reader</code> reads
+   * the data till end-of-file is reached. The driver does the necessary conversion from Java
+   * character format to the national character set in the database.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setNCharacterStream</code> which takes a length parameter.
+   *
+   * @param parameterName the name of the parameter
+   * @param value the parameter value
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the driver
+   *     does not support national character sets; if the driver can detect that a data conversion
+   *     error could occur; if a database access error occurs; or this method is called on a closed
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNCharacterStream(String parameterName, Reader value) throws SQLException {
+    setNCharacterStream(nameToIndex(parameterName), value);
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. This method differs from the
+   * <code>setCharacterStream (int, Reader)</code> method because it informs the driver that the
+   * parameter value should be sent to the server as a <code>CLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGVARCHAR</code> or a
+   * <code>CLOB</code>
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setClob</code> which takes a length parameter.
+   *
+   * @param parameterName the name of the parameter
+   * @param reader An object that contains the data to set the parameter value to.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setClob(String parameterName, Reader reader) throws SQLException {
+    setClob(nameToIndex(parameterName), reader);
+  }
+
+  /**
+   * Sets the designated parameter to an {@code InputStream} object. This method differs from the
+   * <code>setBinaryStream (int, InputStream)</code> method because it informs the driver that the
+   * parameter value should be sent to the server as a <code>BLOB</code>. When the <code>
+   * setBinaryStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGVARBINARY</code> or a
+   * <code>BLOB</code>
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setBlob</code> which takes a length parameter.
+   *
+   * @param parameterName the name of the parameter
+   * @param inputStream An object that contains the data to set the parameter value to.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
+    setBlob(nameToIndex(parameterName), inputStream);
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. This method differs from the
+   * <code>setCharacterStream (int, Reader)</code> method because it informs the driver that the
+   * parameter value should be sent to the server as a <code>NCLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGNVARCHAR</code> or a
+   * <code>NCLOB</code>
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setNClob</code> which takes a length parameter.
+   *
+   * @param parameterName the name of the parameter
+   * @param reader An object that contains the data to set the parameter value to.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if the driver
+   *     does not support national character sets; if the driver can detect that a data conversion
+   *     error could occur; if a database access error occurs or this method is called on a closed
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNClob(String parameterName, Reader reader) throws SQLException {
+    setNClob(nameToIndex(parameterName), reader);
+  }
+
+  /**
+   * Returns an object representing the value of OUT parameter {@code parameterIndex} and will
+   * convert from the SQL type of the parameter to the requested Java data type, if the conversion
+   * is supported. If the conversion is not supported or null is specified for the type, a <code>
+   * SQLException</code> is thrown.
+   *
+   * <p>At a minimum, an implementation must support the conversions defined in Appendix B, Table
+   * B-3 and conversion of appropriate user defined SQL types to a Java type which implements {@code
+   * SQLData}, or {@code Struct}. Additional conversions may be supported and are vendor defined.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param type Class representing the Java data type to convert the designated parameter to.
+   * @return an instance of {@code type} holding the OUT parameter value
+   * @throws SQLException if conversion is not supported, type is null or another error occurs. The
+   *     getCause() method of the exception may provide a more detailed exception, for example, if a
+   *     conversion error occurs
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.7
+   */
+  @Override
+  public <T> T getObject(int parameterIndex, Class<T> type) throws SQLException {
+    checkNotClosed();
+    checkOutputResult();
+    return outputResult.getObject(idxToOutIdx(parameterIndex), type);
+  }
+
+  /**
+   * Returns an object representing the value of OUT parameter {@code parameterName} and will
+   * convert from the SQL type of the parameter to the requested Java data type, if the conversion
+   * is supported. If the conversion is not supported or null is specified for the type, a <code>
+   * SQLException</code> is thrown.
+   *
+   * <p>At a minimum, an implementation must support the conversions defined in Appendix B, Table
+   * B-3 and conversion of appropriate user defined SQL types to a Java type which implements {@code
+   * SQLData}, or {@code Struct}. Additional conversions may be supported and are vendor defined.
+   *
+   * @param parameterName the name of the parameter
+   * @param type Class representing the Java data type to convert the designated parameter to.
+   * @return an instance of {@code type} holding the OUT parameter value
+   * @throws SQLException if conversion is not supported, type is null or another error occurs. The
+   *     getCause() method of the exception may provide a more detailed exception, for example, if a
+   *     conversion error occurs
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.7
+   */
+  @Override
+  public <T> T getObject(String parameterName, Class<T> type) throws SQLException {
+    return getObject(nameToIndex(parameterName), type);
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>If the second argument is an {@code InputStream} then the stream must contain the number of
+   * bytes specified by scaleOrLength. If the second argument is a {@code Reader} then the reader
+   * must contain the number of characters specified by scaleOrLength. If these conditions are not
+   * true the driver will generate a {@code SQLException} when the prepared statement is executed.
+   *
+   * <p>The given Java object will be converted to the given targetSqlType before being sent to the
+   * database.
+   *
+   * <p>If the object has a custom mapping (is of a class implementing the interface {@code
+   * SQLData}), the JDBC driver should call the method {@code SQLData.writeSQL} to write it to the
+   * SQL data stream. If, on the other hand, the object is of a class implementing {@code Ref},
+   * {@code Blob}, {@code Clob}, {@code NClob}, {@code Struct}, {@code java.net.URL}, or {@code
+   * Array}, the driver should pass it to the database as a value of the corresponding SQL type.
+   *
+   * <p>Note that this method may be used to pass database-specific abstract data types.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterName the name of the parameter
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type to be sent to the database. The scale argument may further
+   *     qualify this type.
+   * @param scaleOrLength for {@code java.sql.JDBCType.DECIMAL} or {@code java.sql.JDBCType.NUMERIC
+   *     types}, this is the number of digits after the decimal point. For Java Object types {@code
+   *     InputStream} and {@code Reader}, this is the length of the data in the stream or reader.
+   *     For all other types, this value will be ignored.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed {@code CallableStatement} or if
+   *     the Java Object specified by x is an InputStream or Reader object and the value of the
+   *     scale parameter is less than zero
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void setObject(String parameterName, Object x, SQLType targetSqlType, int scaleOrLength)
+      throws SQLException {
+    setObject(nameToIndex(parameterName), x, targetSqlType, scaleOrLength);
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>This method is similar to {@link #setObject(String parameterName, Object x, SQLType
+   * targetSqlType, int scaleOrLength)}, except that it assumes a scale of zero.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterName the name of the parameter
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type to be sent to the database
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed {@code CallableStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void setObject(String parameterName, Object x, SQLType targetSqlType) throws SQLException {
+    setObject(nameToIndex(parameterName), x, targetSqlType);
+  }
+
+  /**
+   * Registers the OUT parameter in ordinal position {@code parameterIndex} to the JDBC type {@code
+   * sqlType}. All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>The JDBC type specified by {@code sqlType} for an OUT parameter determines the Java type
+   * that must be used in the {@code get} method to read the value of that parameter.
+   *
+   * <p>If the JDBC type expected to be returned to this output parameter is specific to this
+   * particular database, {@code sqlType} may be {@code JDBCType.OTHER} or a {@code SQLType} that is
+   * supported by the JDBC driver. The method {@link #getObject} retrieves the value.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param sqlType the JDBC type code defined by {@code SQLType} to use to register the OUT
+   *     Parameter. If the parameter is of JDBC type {@code JDBCType.NUMERIC} or {@code
+   *     JDBCType.DECIMAL}, the version of {@code registerOutParameter} that accepts a scale value
+   *     should be used.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed {@code CallableStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     sqlType
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void registerOutParameter(int parameterIndex, SQLType sqlType) throws SQLException {
+    registerOutParameter(parameterIndex, 0);
+  }
+
+  /**
+   * Registers the parameter in ordinal position {@code parameterIndex} to be of JDBC type {@code
+   * sqlType}. All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>The JDBC type specified by {@code sqlType} for an OUT parameter determines the Java type
+   * that must be used in the {@code get} method to read the value of that parameter.
+   *
+   * <p>This version of {@code registerOutParameter} should be used when the parameter is of JDBC
+   * type {@code JDBCType.NUMERIC} or {@code JDBCType.DECIMAL}.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, and so on
+   * @param sqlType the JDBC type code defined by {@code SQLType} to use to register the OUT
+   *     Parameter.
+   * @param scale the desired number of digits to the right of the decimal point. It must be greater
+   *     than or equal to zero.
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed {@code CallableStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     sqlType
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void registerOutParameter(int parameterIndex, SQLType sqlType, int scale)
+      throws SQLException {
+    registerOutParameter(parameterIndex, sqlType);
+  }
+
+  /**
+   * Registers the designated output parameter. This version of the method {@code
+   * registerOutParameter} should be used for a user-defined or {@code REF} output parameter.
+   * Examples of user-defined types include: {@code STRUCT}, {@code DISTINCT}, {@code JAVA_OBJECT},
+   * and named array types.
+   *
+   * <p>All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>For a user-defined parameter, the fully-qualified SQL type name of the parameter should also
+   * be given, while a {@code REF} parameter requires that the fully-qualified type name of the
+   * referenced type be given. A JDBC driver that does not need the type code and type name
+   * information may ignore it. To be portable, however, applications should always provide these
+   * values for user-defined and {@code REF} parameters.
+   *
+   * <p>Although it is intended for user-defined and {@code REF} parameters, this method may be used
+   * to register a parameter of any JDBC type. If the parameter does not have a user-defined or
+   * {@code REF} type, the <i>typeName</i> parameter is ignored.
+   *
+   * <p><B>Note:</B> When reading the value of an out parameter, you must use the getter method
+   * whose Java type corresponds to the parameter's registered SQL type.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2,...
+   * @param sqlType the JDBC type code defined by {@code SQLType} to use to register the OUT
+   *     Parameter.
+   * @param typeName the fully-qualified name of an SQL structured type
+   * @throws SQLException if the parameterIndex is not valid; if a database access error occurs or
+   *     this method is called on a closed {@code CallableStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     sqlType
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void registerOutParameter(int parameterIndex, SQLType sqlType, String typeName)
+      throws SQLException {
+    registerOutParameter(parameterIndex, sqlType);
+  }
+
+  /**
+   * Registers the OUT parameter named <code>parameterName</code> to the JDBC type {@code sqlType}.
+   * All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>The JDBC type specified by {@code sqlType} for an OUT parameter determines the Java type
+   * that must be used in the {@code get} method to read the value of that parameter.
+   *
+   * <p>If the JDBC type expected to be returned to this output parameter is specific to this
+   * particular database, {@code sqlType} should be {@code JDBCType.OTHER} or a {@code SQLType} that
+   * is supported by the JDBC driver. The method {@link #getObject} retrieves the value.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType the JDBC type code defined by {@code SQLType} to use to register the OUT
+   *     Parameter. If the parameter is of JDBC type {@code JDBCType.NUMERIC} or {@code
+   *     JDBCType.DECIMAL}, the version of {@code registerOutParameter} that accepts a scale value
+   *     should be used.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed {@code CallableStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     sqlType or if the JDBC driver does not support this method
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void registerOutParameter(String parameterName, SQLType sqlType) throws SQLException {
+    registerOutParameter(nameToIndex(parameterName), sqlType);
+  }
+
+  /**
+   * Registers the parameter named <code>parameterName</code> to be of JDBC type {@code sqlType}.
+   * All OUT parameters must be registered before a stored procedure is executed.
+   *
+   * <p>The JDBC type specified by {@code sqlType} for an OUT parameter determines the Java type
+   * that must be used in the {@code get} method to read the value of that parameter.
+   *
+   * <p>This version of {@code registerOutParameter} should be used when the parameter is of JDBC
+   * type {@code JDBCType.NUMERIC} or {@code JDBCType.DECIMAL}.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType the JDBC type code defined by {@code SQLType} to use to register the OUT
+   *     Parameter.
+   * @param scale the desired number of digits to the right of the decimal point. It must be greater
+   *     than or equal to zero.
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed {@code CallableStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     sqlType or if the JDBC driver does not support this method
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void registerOutParameter(String parameterName, SQLType sqlType, int scale)
+      throws SQLException {
+    registerOutParameter(nameToIndex(parameterName), sqlType);
+  }
+
+  /**
+   * Registers the designated output parameter. This version of the method {@code
+   * registerOutParameter} should be used for a user-named or REF output parameter. Examples of
+   * user-named types include: STRUCT, DISTINCT, JAVA_OBJECT, and named array types.
+   *
+   * <p>All OUT parameters must be registered before a stored procedure is executed. For a
+   * user-named parameter the fully-qualified SQL type name of the parameter should also be given,
+   * while a REF parameter requires that the fully-qualified type name of the referenced type be
+   * given. A JDBC driver that does not need the type code and type name information may ignore it.
+   * To be portable, however, applications should always provide these values for user-named and REF
+   * parameters.
+   *
+   * <p>Although it is intended for user-named and REF parameters, this method may be used to
+   * register a parameter of any JDBC type. If the parameter does not have a user-named or REF type,
+   * the typeName parameter is ignored.
+   *
+   * <p><B>Note:</B> When reading the value of an out parameter, you must use the {@code getXXX}
+   * method whose Java type XXX corresponds to the parameter's registered SQL type.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterName the name of the parameter
+   * @param sqlType the JDBC type code defined by {@code SQLType} to use to register the OUT
+   *     Parameter.
+   * @param typeName the fully-qualified name of an SQL structured type
+   * @throws SQLException if parameterName does not correspond to a named parameter; if a database
+   *     access error occurs or this method is called on a closed {@code CallableStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     sqlType or if the JDBC driver does not support this method
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void registerOutParameter(String parameterName, SQLType sqlType, String typeName)
+      throws SQLException {
+    registerOutParameter(nameToIndex(parameterName), sqlType);
+  }
+
+  @Override
+  public CallableParameterMetaData getParameterMetaData() throws SQLException {
+    PreparedStatement prep =
+        new ClientPreparedStatement(
+            "SELECT * from information_schema.PARAMETERS "
+                + "WHERE SPECIFIC_NAME = ? "
+                + "AND SPECIFIC_SCHEMA = ? "
+                + "ORDER BY ORDINAL_POSITION",
+            con,
+            lock,
+            false,
+            false,
+            Statement.NO_GENERATED_KEYS,
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_READ_ONLY,
+            0);
+    prep.setString(1, procedureName);
+    prep.setString(2, databaseName);
+    ResultSet rs = prep.executeQuery();
+    parameterMetaData = new CallableParameterMetaData(rs, isFunction());
+    return parameterMetaData;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/BasePreparedStatement.java b/src/main/java/org/mariadb/jdbc/BasePreparedStatement.java
new file mode 100644
index 0000000..3a7eab2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/BasePreparedStatement.java
@@ -0,0 +1,1589 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.sql.Date;
+import java.sql.ParameterMetaData;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.codec.*;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.plugin.codec.*;
+import org.mariadb.jdbc.util.ParameterList;
+
+/** Common methods for prepare statement, for client and server prepare statement. */
+public abstract class BasePreparedStatement extends Statement implements PreparedStatement {
+
+  /** parameters */
+  protected Parameters parameters;
+
+  /** batching parameters */
+  protected List<Parameters> batchParameters;
+
+  /** prepare statement sql command */
+  protected final String sql;
+
+  /** PREPARE command result */
+  protected Prepare prepareResult = null;
+
+  /**
+   * Constructor
+   *
+   * @param sql sql command
+   * @param con connection
+   * @param lock thread safe lock
+   * @param canUseServerTimeout indicate if server can support server timeout
+   * @param canUseServerMaxRows indicate if server can support max rows
+   * @param autoGeneratedKeys indicate if automatif generated key retrival is required
+   * @param resultSetType resultset type
+   * @param resultSetConcurrency resultset concurrency
+   * @param defaultFetchSize default fetch size
+   */
+  public BasePreparedStatement(
+      String sql,
+      Connection con,
+      ReentrantLock lock,
+      boolean canUseServerTimeout,
+      boolean canUseServerMaxRows,
+      int autoGeneratedKeys,
+      int resultSetType,
+      int resultSetConcurrency,
+      int defaultFetchSize) {
+    super(
+        con,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        autoGeneratedKeys,
+        resultSetType,
+        resultSetConcurrency,
+        defaultFetchSize);
+    this.sql = sql;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("sql:'" + sql + "'");
+    sb.append(", parameters:[");
+    for (int i = 0; i < parameters.size(); i++) {
+      org.mariadb.jdbc.client.util.Parameter param = parameters.get(i);
+      if (param == null) {
+        sb.append("null");
+      } else {
+        sb.append(param.bestEffortStringValue(con.getContext()));
+      }
+      if (i != parameters.size() - 1) {
+        sb.append(",");
+      }
+    }
+    sb.append("]");
+    return sb.toString();
+  }
+
+  /**
+   * Set PREPARE result
+   *
+   * @param prepareResult prepare result
+   */
+  public void setPrepareResult(Prepare prepareResult) {
+    this.prepareResult = prepareResult;
+  }
+
+  /**
+   * Get cached metadata list
+   *
+   * @return metadata list
+   */
+  public ColumnDecoder[] getMeta() {
+    return this.prepareResult.getColumns();
+  }
+
+  /**
+   * update cached metadata list
+   *
+   * @param ci metadata columns
+   */
+  public void updateMeta(ColumnDecoder[] ci) {
+    this.prepareResult.setColumns(ci);
+  }
+
+  public abstract boolean execute() throws SQLException;
+
+  public abstract ResultSet executeQuery() throws SQLException;
+
+  public abstract int executeUpdate() throws SQLException;
+
+  public abstract long executeLargeUpdate() throws SQLException;
+
+  public abstract void addBatch() throws SQLException;
+
+  public abstract ResultSetMetaData getMetaData() throws SQLException;
+
+  public abstract ParameterMetaData getParameterMetaData() throws SQLException;
+
+  /**
+   * Set all parameters
+   *
+   * @param parameters parameters
+   */
+  public void setParameters(Parameters parameters) {
+    this.parameters = parameters;
+  }
+
+  /**
+   * Set parameter
+   *
+   * @param index parameter index
+   * @param param parameter
+   */
+  public void setParameter(int index, org.mariadb.jdbc.client.util.Parameter param) {
+    parameters.set(index, param);
+  }
+
+  @Override
+  public abstract int[] executeBatch() throws SQLException;
+
+  @Override
+  public abstract long[] executeLargeBatch() throws SQLException;
+
+  // ***************************************************************************************************
+  // methods inherited from Statement that are disabled
+  // ***************************************************************************************************
+
+  @Override
+  public void addBatch(String sql) throws SQLException {
+    throw exceptionFactory().create("addBatch(String sql) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public boolean execute(String sql) throws SQLException {
+    throw exceptionFactory().create("execute(String sql) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+    throw exceptionFactory()
+        .create("execute(String sql, int autoGeneratedKeys) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+    throw exceptionFactory()
+        .create("execute(String sql, int[] columnIndexes) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public boolean execute(String sql, String[] columnNames) throws SQLException {
+    throw exceptionFactory()
+        .create("execute(String sql, String[] columnNames) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public ResultSet executeQuery(String sql) throws SQLException {
+    throw exceptionFactory()
+        .create("executeQuery(String sql) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public int executeUpdate(String sql) throws SQLException {
+    throw exceptionFactory()
+        .create("executeUpdate(String sql) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+    throw exceptionFactory()
+        .create(
+            "executeUpdate(String sql, int autoGeneratedKeys) cannot be called on"
+                + " preparedStatement");
+  }
+
+  @Override
+  public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+    throw exceptionFactory()
+        .create(
+            "executeUpdate(String sql, int[] columnIndexes) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+    throw exceptionFactory()
+        .create(
+            "executeUpdate(String sql, String[] columnNames) cannot be called on"
+                + " preparedStatement");
+  }
+
+  @Override
+  public long executeLargeUpdate(String sql) throws SQLException {
+    throw exceptionFactory()
+        .create("executeLargeUpdate(String sql) cannot be called on preparedStatement");
+  }
+
+  @Override
+  public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+    throw exceptionFactory()
+        .create(
+            "executeLargeUpdate(String sql, int autoGeneratedKeys) cannot be called on"
+                + " preparedStatement");
+  }
+
+  @Override
+  public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
+    throw exceptionFactory()
+        .create(
+            "executeLargeUpdate(String sql, int[] columnIndexes) cannot be called on"
+                + " preparedStatement");
+  }
+
+  @Override
+  public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
+    throw exceptionFactory()
+        .create(
+            "executeLargeUpdate(String sql, String[] columnNames) cannot be called on"
+                + " preparedStatement");
+  }
+
+  // ***************************************************************************************************
+  // Setters
+  // ***************************************************************************************************
+
+  private void checkIndex(int index) throws SQLException {
+    if (index <= 0) {
+      throw exceptionFactory().create(String.format("wrong parameter index %s", index));
+    }
+  }
+
+  /**
+   * Sets the designated parameter to SQL <code>NULL</code>.
+   *
+   * <p><B>Note:</B> You must specify the parameter's SQL type.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param sqlType the SQL type code defined in <code>java.sql.Types</code>
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type
+   */
+  @Override
+  public void setNull(int parameterIndex, int sqlType) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, Parameter.NULL_PARAMETER);
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>boolean</code> value. The driver converts
+   * this to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new NonNullParameter<>(BooleanCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>byte</code> value. The driver converts
+   * this to an SQL <code>TINYINT</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setByte(int parameterIndex, byte x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new NonNullParameter<>(ByteCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>short</code> value. The driver converts
+   * this to an SQL <code>SMALLINT</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setShort(int parameterIndex, short x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new NonNullParameter<>(ShortCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>int</code> value. The driver converts
+   * this to an SQL <code>INTEGER</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setInt(int parameterIndex, int x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new NonNullParameter<>(IntCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>long</code> value. The driver converts
+   * this to an SQL <code>BIGINT</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setLong(int parameterIndex, long x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new NonNullParameter<>(LongCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>float</code> value. The driver converts
+   * this to an SQL <code>REAL</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setFloat(int parameterIndex, float x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new NonNullParameter<>(FloatCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>double</code> value. The driver converts
+   * this to an SQL <code>DOUBLE</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setDouble(int parameterIndex, double x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new NonNullParameter<>(DoubleCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.math.BigDecimal</code> value. The driver
+   * converts this to an SQL <code>NUMERIC</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(BigDecimalCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java <code>String</code> value. The driver converts
+   * this to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value (depending on the
+   * argument's size relative to the driver's limits on <code>VARCHAR</code> values) when it sends
+   * it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setString(int parameterIndex, String x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StringCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given Java array of bytes. The driver converts this to an
+   * SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code> (depending on the argument's size
+   * relative to the driver's limits on <code>VARBINARY</code> values) when it sends it to the
+   * database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ByteArrayCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Date</code> value using the default
+   * time zone of the virtual machine that is running the application. The driver converts this to
+   * an SQL <code>DATE</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setDate(int parameterIndex, Date x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(DateCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Time</code> value. The driver
+   * converts this to an SQL <code>TIME</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setTime(int parameterIndex, Time x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(TimeCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value. The driver
+   * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(TimestampCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large ASCII value is input to a <code>LONGVARCHAR</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code>. Data will be read from
+   * the stream as needed until end-of-file is reached. The JDBC driver will do any necessary
+   * conversion from ASCII to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the Java input stream that contains the ASCII parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length));
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes.
+   *
+   * <p>When a very large Unicode value is input to a <code>LONGVARCHAR</code> parameter, it may be
+   * more practical to send it via a <code>java.io.InputStream</code> object. The data will be read
+   * from the stream as needed until end-of-file is reached. The JDBC driver will do any necessary
+   * conversion from Unicode to the database char format.
+   *
+   * <p>The byte format of the Unicode stream must be a Java UTF-8, as defined in the Java Virtual
+   * Machine Specification.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x a <code>java.io.InputStream</code> object that contains the Unicode parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @deprecated Use {@code setCharacterStream}
+   */
+  @Override
+  @Deprecated
+  public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length));
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large binary value is input to a <code>LONGVARBINARY</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code> object. The data will
+   * be read from the stream as needed until end-of-file is reached.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the java input stream which contains the binary parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   */
+  @Override
+  public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length));
+  }
+
+  /**
+   * Clears the current parameter values immediately.
+   *
+   * <p>In general, parameter values remain in force for repeated use of a statement. Setting a
+   * parameter value automatically clears its previous value. However, in some cases it is useful to
+   * immediately release the resources used by the current parameter values; this can be done by
+   * calling the method <code>clearParameters</code>.
+   *
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>PreparedStatement</code>
+   */
+  @Override
+  public void clearParameters() throws SQLException {
+    checkNotClosed();
+    parameters = new ParameterList();
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>This method is similar to {@link #setObject(int parameterIndex, Object x, int targetSqlType,
+   * int scaleOrLength)}, except that it assumes a scale of zero.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent to the database
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed
+   *     PreparedStatement
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see Types
+   */
+  @Override
+  public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+    setInternalObject(parameterIndex, x, targetSqlType, null);
+  }
+
+  /**
+   * Sets the value of the designated parameter using the given object.
+   *
+   * <p>The JDBC specification specifies a standard mapping from Java <code>Object</code> types to
+   * SQL types. The given argument will be converted to the corresponding SQL type before being sent
+   * to the database.
+   *
+   * <p>Note that this method may be used to pass datatabase- specific abstract data types, by using
+   * a driver-specific Java type.
+   *
+   * <p>If the object is of a class implementing the interface <code>SQLData</code>, the JDBC driver
+   * should call the method <code>SQLData.writeSQL</code> to write it to the SQL data stream. If, on
+   * the other hand, the object is of a class implementing <code>Ref</code>, <code>Blob</code>,
+   * <code>Clob</code>, <code>NClob</code>, <code>Struct</code>, <code>java.net.URL</code>, <code>
+   * RowId</code>, <code>SQLXML</code> or <code>Array</code>, the driver should pass it to the
+   * database as a value of the corresponding SQL type.
+   *
+   * <p><b>Note:</b> Not all databases allow for a non-typed Null to be sent to the backend. For
+   * maximum portability, the <code>setNull</code> or the <code>
+   * setObject(int parameterIndex, Object x, int sqlType)</code> method should be used instead of
+   * <code>setObject(int parameterIndex, Object x)</code>.
+   *
+   * <p><b>Note:</b> This method throws an exception if there is an ambiguity, for example, if the
+   * object is of a class implementing more than one of the interfaces named above.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the object containing the input parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs; this method is called on a closed <code>
+   *     PreparedStatement</code> or the type of the given object is ambiguous
+   */
+  @Override
+  public void setObject(int parameterIndex, Object x) throws SQLException {
+    setInternalObject(parameterIndex, x, null, null);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>Reader</code> object, which is the given
+   * number of characters long. When a very large UNICODE value is input to a <code>LONGVARCHAR
+   * </code> parameter, it may be more practical to send it via a <code>java.io.Reader</code>
+   * object. The data will be read from the stream as needed until end-of-file is reached. The JDBC
+   * driver will do any necessary conversion from UNICODE to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param reader the <code>java.io.Reader</code> object that contains the Unicode data
+   * @param length the number of characters in the stream
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @since 1.2
+   */
+  @Override
+  public void setCharacterStream(int parameterIndex, Reader reader, int length)
+      throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(
+        parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, (long) length));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>REF(&lt;structured-type&gt;)</code> value. The
+   * driver converts this to an SQL <code>REF</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x an SQL <code>REF</code> value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public void setRef(int parameterIndex, Ref x) throws SQLException {
+    throw exceptionFactory().notSupported("REF parameter are not supported");
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Blob</code> object. The driver
+   * converts this to an SQL <code>BLOB</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public void setBlob(int parameterIndex, Blob x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(BlobCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Clob</code> object. The driver
+   * converts this to an SQL <code>CLOB</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public void setClob(int parameterIndex, Clob x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ClobCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Array</code> object. The driver
+   * converts this to an SQL <code>ARRAY</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x an <code>Array</code> object that maps an SQL <code>ARRAY</code> value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public void setArray(int parameterIndex, Array x) throws SQLException {
+    throw exceptionFactory().notSupported("Array parameter are not supported");
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Date</code> value, using the given
+   * <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to construct an
+   * SQL <code>DATE</code> value, which the driver then sends to the database. With a <code>Calendar
+   * </code> object, the driver can calculate the date taking into account a custom timezone. If no
+   * <code>Calendar</code> object is specified, the driver uses the default timezone, which is that
+   * of the virtual machine running the application.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @param cal the <code>Calendar</code> object the driver will use to construct the date
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @since 1.2
+   */
+  @Override
+  public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new ParameterWithCal<>(DateCodec.INSTANCE, x, cal));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Time</code> value, using the given
+   * <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to construct an
+   * SQL <code>TIME</code> value, which the driver then sends to the database. With a <code>Calendar
+   * </code> object, the driver can calculate the time taking into account a custom timezone. If no
+   * <code>Calendar</code> object is specified, the driver uses the default timezone, which is that
+   * of the virtual machine running the application.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @param cal the <code>Calendar</code> object the driver will use to construct the time
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @since 1.2
+   */
+  @Override
+  public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new ParameterWithCal<>(TimeCodec.INSTANCE, x, cal));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value, using the
+   * given <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to
+   * construct an SQL <code>TIMESTAMP</code> value, which the driver then sends to the database.
+   * With a <code>Calendar</code> object, the driver can calculate the timestamp taking into account
+   * a custom timezone. If no <code>Calendar</code> object is specified, the driver uses the default
+   * timezone, which is that of the virtual machine running the application.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @param cal the <code>Calendar</code> object the driver will use to construct the timestamp
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @since 1.2
+   */
+  @Override
+  public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new ParameterWithCal<>(TimestampCodec.INSTANCE, x, cal));
+  }
+
+  /**
+   * Sets the designated parameter to SQL <code>NULL</code>. This version of the method <code>
+   * setNull</code> should be used for user-defined types and REF type parameters. Examples of
+   * user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and named array types.
+   *
+   * <p><B>Note:</B> To be portable, applications must give the SQL type code and the
+   * fully-qualified SQL type name when specifying a NULL user-defined or REF parameter. In the case
+   * of a user-defined type the name is the type name of the parameter itself. For a REF parameter,
+   * the name is the type name of the referenced type. If a JDBC driver does not need the type code
+   * or type name information, it may ignore it.
+   *
+   * <p>Although it is intended for user-defined and Ref parameters, this method may be used to set
+   * a null parameter of any JDBC type. If the parameter does not have a user-defined or REF type,
+   * the given typeName is ignored.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param sqlType a value from <code>java.sql.Types</code>
+   * @param typeName the fully-qualified name of an SQL user-defined type; ignored if the parameter
+   *     is not a user-defined type or REF
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code>
+   *     BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>
+   *     NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code>
+   *     REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and
+   *     the JDBC driver does not support this data type or if the JDBC driver does not support this
+   *     method
+   * @since 1.2
+   */
+  @Override
+  public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, Parameter.NULL_PARAMETER);
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.net.URL</code> value. The driver converts
+   * this to an SQL <code>DATALINK</code> value when it sends it to the database.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the <code>java.net.URL</code> object to be set
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public void setURL(int parameterIndex, URL x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StringCodec.INSTANCE, x.toString()));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The driver
+   * converts this to an SQL <code>ROWID</code> value when it sends it to the database
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setRowId(int parameterIndex, RowId x) throws SQLException {
+    throw exceptionFactory().notSupported("RowId parameter are not supported");
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>String</code> object. The driver converts this
+   * to an SQL <code>NCHAR</code> or <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
+   * (depending on the argument's size relative to the driver's limits on <code>NVARCHAR</code>
+   * values) when it sends it to the database.
+   *
+   * @param parameterIndex of the first parameter is 1, the second is 2, ...
+   * @param value the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if the driver does not support national character sets; if the driver can detect
+   *     that a data conversion error could occur; if a database access error occurs; or this method
+   *     is called on a closed <code>PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNString(int parameterIndex, String value) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StringCodec.INSTANCE, value));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The <code>Reader</code> reads
+   * the data till end-of-file is reached. The driver does the necessary conversion from Java
+   * character format to the national character set in the database.
+   *
+   * @param parameterIndex of the first parameter is 1, the second is 2, ...
+   * @param value the parameter value
+   * @param length the number of characters in the parameter data.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if the driver does not support national character sets; if the driver can detect
+   *     that a data conversion error could occur; if a database access error occurs; or this method
+   *     is called on a closed <code>PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNCharacterStream(int parameterIndex, Reader value, long length)
+      throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, value, length));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this
+   * to an SQL <code>NCLOB</code> value when it sends it to the database.
+   *
+   * @param parameterIndex of the first parameter is 1, the second is 2, ...
+   * @param value the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if the driver does not support national character sets; if the driver can detect
+   *     that a data conversion error could occur; if a database access error occurs; or this method
+   *     is called on a closed <code>PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNClob(int parameterIndex, NClob value) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ClobCodec.INSTANCE, value));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the
+   * number of characters specified by length otherwise a <code>SQLException</code> will be
+   * generated when the <code>PreparedStatement</code> is executed. This method differs from the
+   * <code>setCharacterStream (int, Reader, int)</code> method because it informs the driver that
+   * the parameter value should be sent to the server as a <code>CLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGVARCHAR</code> or a
+   * <code>CLOB</code>
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @param reader An object that contains the data to set the parameter value to.
+   * @param length the number of characters in the parameter data.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs; this method is called on a closed <code>
+   *     PreparedStatement</code> or if the length specified is less than zero.
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, length));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>InputStream</code> object. The inputstream must
+   * contain the number of characters specified by length otherwise a <code>SQLException</code> will
+   * be generated when the <code>PreparedStatement</code> is executed. This method differs from the
+   * <code>setBinaryStream (int, InputStream, int)</code> method because it informs the driver that
+   * the parameter value should be sent to the server as a <code>BLOB</code>. When the <code>
+   * setBinaryStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGVARBINARY</code> or a
+   * <code>BLOB</code>
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @param inputStream An object that contains the data to set the parameter value to.
+   * @param length the number of bytes in the parameter data.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs; this method is called on a closed <code>
+   *     PreparedStatement</code>; if the length specified is less than zero or if the number of
+   *     bytes in the inputstream does not match the specified length.
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBlob(int parameterIndex, InputStream inputStream, long length)
+      throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, inputStream, length));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the
+   * number of characters specified by length otherwise a <code>SQLException</code> will be
+   * generated when the <code>PreparedStatement</code> is executed. This method differs from the
+   * <code>setCharacterStream (int, Reader, int)</code> method because it informs the driver that
+   * the parameter value should be sent to the server as a <code>NCLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGNVARCHAR</code> or a
+   * <code>NCLOB</code>
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @param reader An object that contains the data to set the parameter value to.
+   * @param length the number of characters in the parameter data.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if the length specified is less than zero; if the driver does not support
+   *     national character sets; if the driver can detect that a data conversion error could occur;
+   *     if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, length));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver
+   * converts this to an SQL <code>XML</code> value when it sends it to the database.
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs; this method is called on a closed <code>
+   *     PreparedStatement</code> or the <code>java.xml.transform.Result</code>, <code>Writer</code>
+   *     or <code>OutputStream</code> has not been closed for the <code>SQLXML</code> object
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+    throw exceptionFactory().notSupported("SQLXML parameter are not supported");
+  }
+
+  private ExceptionFactory exceptionFactory() {
+    return con.getExceptionFactory().of(this);
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>If the second argument is an <code>InputStream</code> then the stream must contain the
+   * number of bytes specified by scaleOrLength. If the second argument is a <code>Reader</code>
+   * then the reader must contain the number of characters specified by scaleOrLength. If these
+   * conditions are not true the driver will generate a <code>SQLException</code> when the prepared
+   * statement is executed.
+   *
+   * <p>The given Java object will be converted to the given targetSqlType before being sent to the
+   * database.
+   *
+   * <p>If the object has a custom mapping (is of a class implementing the interface <code>SQLData
+   * </code>), the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it to
+   * the SQL data stream. If, on the other hand, the object is of a class implementing <code>Ref
+   * </code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, <code>Struct</code>, <code>
+   * java.net.URL</code>, or <code>Array</code>, the driver should pass it to the database as a
+   * value of the corresponding SQL type.
+   *
+   * <p>Note that this method may be used to pass database-specific abstract data types.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent to the database.
+   *     The scale argument may further qualify this type.
+   * @param scaleOrLength for <code>java.sql.Types.DECIMAL</code> or <code>
+   *     java.sql.Types.NUMERIC types</code>, this is the number of digits after the decimal point.
+   *     For Java Object types <code>InputStream</code> and <code>Reader</code>, this is the length
+   *     of the data in the stream or reader. For all other types, this value will be ignored.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs; this method is called on a closed <code>
+   *     PreparedStatement</code> or if the Java Object specified by x is an InputStream or Reader
+   *     object and the value of the scale parameter is less than zero
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see Types
+   */
+  @Override
+  public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength)
+      throws SQLException {
+    setInternalObject(parameterIndex, x, targetSqlType, (long) scaleOrLength);
+  }
+
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  private void setInternalObject(
+      int parameterIndex, Object obj, Integer targetSqlType, Long scaleOrLength)
+      throws SQLException {
+    checkIndex(parameterIndex);
+    if (obj == null) {
+      parameters.set(parameterIndex - 1, Parameter.NULL_PARAMETER);
+      return;
+    }
+
+    if (targetSqlType != null) {
+      // target type is defined.
+      // in case of not corresponding data type, converting
+      switch (targetSqlType) {
+        case Types.ARRAY:
+        case Types.DATALINK:
+        case Types.JAVA_OBJECT:
+        case Types.REF:
+        case Types.ROWID:
+        case Types.SQLXML:
+        case Types.STRUCT:
+          throw exceptionFactory().notSupported("Type not supported");
+        default:
+          break;
+      }
+
+      if (obj instanceof String || obj instanceof Character) {
+        if (targetSqlType == Types.BLOB) {
+          throw exceptionFactory()
+              .create(
+                  String.format(
+                      "Cannot convert a %s to a Blob",
+                      obj instanceof String ? "string" : "character"));
+        }
+        String str = obj instanceof String ? (String) obj : ((Character) obj).toString();
+        try {
+          switch (targetSqlType) {
+            case Types.BIT:
+            case Types.BOOLEAN:
+              setBoolean(parameterIndex, !("false".equalsIgnoreCase(str) || "0".equals(str)));
+              return;
+            case Types.TINYINT:
+              setByte(parameterIndex, Byte.parseByte(str));
+              return;
+            case Types.SMALLINT:
+              setShort(parameterIndex, Short.parseShort(str));
+              return;
+            case Types.INTEGER:
+              setInt(parameterIndex, Integer.parseInt(str));
+              return;
+            case Types.DOUBLE:
+            case Types.FLOAT:
+              setDouble(parameterIndex, Double.valueOf(str));
+              return;
+            case Types.REAL:
+              setFloat(parameterIndex, Float.valueOf(str));
+              return;
+            case Types.BIGINT:
+              setLong(parameterIndex, Long.valueOf(str));
+              return;
+            case Types.DECIMAL:
+            case Types.NUMERIC:
+              setBigDecimal(parameterIndex, new BigDecimal(str));
+              return;
+            case Types.CLOB:
+            case Types.NCLOB:
+            case Types.CHAR:
+            case Types.VARCHAR:
+            case Types.LONGVARCHAR:
+            case Types.NCHAR:
+            case Types.NVARCHAR:
+            case Types.LONGNVARCHAR:
+              setString(parameterIndex, str);
+              return;
+            case Types.TIMESTAMP:
+              if (str.startsWith("0000-00-00")) {
+                setTimestamp(parameterIndex, null);
+              } else {
+                setTimestamp(parameterIndex, Timestamp.valueOf(str));
+              }
+              return;
+            case Types.TIME:
+              setTime(parameterIndex, Time.valueOf((String) obj));
+              return;
+            default:
+              throw exceptionFactory()
+                  .create(String.format("Could not convert [%s] to %s", str, targetSqlType));
+          }
+        } catch (IllegalArgumentException e) {
+          throw exceptionFactory()
+              .create(
+                  String.format("Could not convert [%s] to java.sql.Type %s", str, targetSqlType),
+                  "HY000",
+                  e);
+        }
+      } else if (obj instanceof Number) {
+        Number bd = (Number) obj;
+        switch (targetSqlType) {
+          case Types.TINYINT:
+            setByte(parameterIndex, bd.byteValue());
+            return;
+          case Types.SMALLINT:
+            setShort(parameterIndex, bd.shortValue());
+            return;
+          case Types.INTEGER:
+            setInt(parameterIndex, bd.intValue());
+            return;
+          case Types.BIGINT:
+            setLong(parameterIndex, bd.longValue());
+            return;
+          case Types.FLOAT:
+          case Types.DOUBLE:
+            setDouble(parameterIndex, bd.doubleValue());
+            return;
+          case Types.REAL:
+            setFloat(parameterIndex, bd.floatValue());
+            return;
+          case Types.DECIMAL:
+          case Types.NUMERIC:
+            if (obj instanceof BigDecimal) {
+              setBigDecimal(parameterIndex, (BigDecimal) obj);
+            } else if (obj instanceof Double || obj instanceof Float) {
+              setDouble(parameterIndex, bd.doubleValue());
+            } else {
+              setLong(parameterIndex, bd.longValue());
+            }
+            return;
+          case Types.BIT:
+            setBoolean(parameterIndex, bd.shortValue() != 0);
+            return;
+          case Types.CHAR:
+          case Types.VARCHAR:
+            setString(parameterIndex, bd.toString());
+            return;
+          default:
+            throw exceptionFactory()
+                .create(String.format("Could not convert [%s] to %s", bd, targetSqlType));
+        }
+      } else if (obj instanceof byte[]) {
+        if (targetSqlType == Types.BINARY
+            || targetSqlType == Types.VARBINARY
+            || targetSqlType == Types.LONGVARBINARY) {
+          setBytes(parameterIndex, (byte[]) obj);
+          return;
+        } else if (targetSqlType == Types.BLOB) {
+          setBlob(parameterIndex, new MariaDbBlob((byte[]) obj));
+        } else {
+          throw exceptionFactory()
+              .create("Can only convert a byte[] to BINARY, VARBINARY, LONGVARBINARY or BLOB type");
+        }
+      }
+    }
+
+    // in case parameter still not set, defaulting to object type
+    for (Codec<?> codec : con.getContext().getConf().codecs()) {
+      if (codec.canEncode(obj)) {
+        Parameter p = new Parameter(codec, obj, scaleOrLength);
+        parameters.set(parameterIndex - 1, p);
+        return;
+      }
+    }
+
+    throw new SQLException(String.format("Type %s not supported type", obj.getClass().getName()));
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large ASCII value is input to a <code>LONGVARCHAR</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code>. Data will be read from
+   * the stream as needed until end-of-file is reached. The JDBC driver will do any necessary
+   * conversion from ASCII to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the Java input stream that contains the ASCII parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @since 1.6
+   */
+  @Override
+  public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, length));
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream, which will have the specified number
+   * of bytes. When a very large binary value is input to a <code>LONGVARBINARY</code> parameter, it
+   * may be more practical to send it via a <code>java.io.InputStream</code> object. The data will
+   * be read from the stream as needed until end-of-file is reached.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the java input stream which contains the binary parameter value
+   * @param length the number of bytes in the stream
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @since 1.6
+   */
+  @Override
+  public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, length));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>Reader</code> object, which is the given
+   * number of characters long. When a very large UNICODE value is input to a <code>LONGVARCHAR
+   * </code> parameter, it may be more practical to send it via a <code>java.io.Reader</code>
+   * object. The data will be read from the stream as needed until end-of-file is reached. The JDBC
+   * driver will do any necessary conversion from UNICODE to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param reader the <code>java.io.Reader</code> object that contains the Unicode data
+   * @param length the number of characters in the stream
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @since 1.6
+   */
+  @Override
+  public void setCharacterStream(int parameterIndex, Reader reader, long length)
+      throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, length));
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream. When a very large ASCII value is input
+   * to a <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a <code>
+   * java.io.InputStream</code>. Data will be read from the stream as needed until end-of-file is
+   * reached. The JDBC driver will do any necessary conversion from ASCII to the database char
+   * format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setAsciiStream</code> which takes a length parameter.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the Java input stream that contains the ASCII parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given input stream. When a very large binary value is
+   * input to a <code>LONGVARBINARY</code> parameter, it may be more practical to send it via a
+   * <code>java.io.InputStream</code> object. The data will be read from the stream as needed until
+   * end-of-file is reached.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setBinaryStream</code> which takes a length parameter.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the java input stream which contains the binary parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x));
+  }
+
+  /**
+   * Sets the designated parameter to the given <code>Reader</code> object. When a very large
+   * UNICODE value is input to a <code>LONGVARCHAR</code> parameter, it may be more practical to
+   * send it via a <code>java.io.Reader</code> object. The data will be read from the stream as
+   * needed until end-of-file is reached. The JDBC driver will do any necessary conversion from
+   * UNICODE to the database char format.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setCharacterStream</code> which takes a length parameter.
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param reader the <code>java.io.Reader</code> object that contains the Unicode data
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed <code>
+   *     PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. The <code>Reader</code> reads
+   * the data till end-of-file is reached. The driver does the necessary conversion from Java
+   * character format to the national character set in the database.
+   *
+   * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own
+   * subclass that implements the standard interface.
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setNCharacterStream</code> which takes a length parameter.
+   *
+   * @param parameterIndex of the first parameter is 1, the second is 2, ...
+   * @param value the parameter value
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if the driver does not support national character sets; if the driver can detect
+   *     that a data conversion error could occur; if a database access error occurs; or this method
+   *     is called on a closed <code>PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, value));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. This method differs from the
+   * <code>setCharacterStream (int, Reader)</code> method because it informs the driver that the
+   * parameter value should be sent to the server as a <code>CLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGVARCHAR</code> or a
+   * <code>CLOB</code>
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setClob</code> which takes a length parameter.
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @param reader An object that contains the data to set the parameter value to.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs; this method is called on a closed <code>
+   *     PreparedStatement</code>or if parameterIndex does not correspond to a parameter marker in
+   *     the SQL statement
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setClob(int parameterIndex, Reader reader) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>InputStream</code> object. This method differs from
+   * the <code>setBinaryStream (int, InputStream)</code> method because it informs the driver that
+   * the parameter value should be sent to the server as a <code>BLOB</code>. When the <code>
+   * setBinaryStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGVARBINARY</code> or a
+   * <code>BLOB</code>
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setBlob</code> which takes a length parameter.
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @param inputStream An object that contains the data to set the parameter value to.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs; this method is called on a closed <code>
+   *     PreparedStatement</code> or if parameterIndex does not correspond to a parameter marker in
+   *     the SQL statement,
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, inputStream));
+  }
+
+  /**
+   * Sets the designated parameter to a <code>Reader</code> object. This method differs from the
+   * <code>setCharacterStream (int, Reader)</code> method because it informs the driver that the
+   * parameter value should be sent to the server as a <code>NCLOB</code>. When the <code>
+   * setCharacterStream</code> method is used, the driver may have to do extra work to determine
+   * whether the parameter data should be sent to the server as a <code>LONGNVARCHAR</code> or a
+   * <code>NCLOB</code>
+   *
+   * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more
+   * efficient to use a version of <code>setNClob</code> which takes a length parameter.
+   *
+   * @param parameterIndex index of the first parameter is 1, the second is 2, ...
+   * @param reader An object that contains the data to set the parameter value to.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if the driver does not support national character sets; if the driver can detect
+   *     that a data conversion error could occur; if a database access error occurs or this method
+   *     is called on a closed <code>PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.6
+   */
+  @Override
+  public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+    checkIndex(parameterIndex);
+    parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader));
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>If the second argument is an {@code InputStream} then the stream must contain the number of
+   * bytes specified by scaleOrLength. If the second argument is a {@code Reader} then the reader
+   * must contain the number of characters specified by scaleOrLength. If these conditions are not
+   * true the driver will generate a {@code SQLException} when the prepared statement is executed.
+   *
+   * <p>The given Java object will be converted to the given targetSqlType before being sent to the
+   * database.
+   *
+   * <p>If the object has a custom mapping (is of a class implementing the interface {@code
+   * SQLData}), the JDBC driver should call the method {@code SQLData.writeSQL} to write it to the
+   * SQL data stream. If, on the other hand, the object is of a class implementing {@code Ref},
+   * {@code Blob}, {@code Clob}, {@code NClob}, {@code Struct}, {@code java.net.URL}, or {@code
+   * Array}, the driver should pass it to the database as a value of the corresponding SQL type.
+   *
+   * <p>Note that this method may be used to pass database-specific abstract data types.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type to be sent to the database. The scale argument may further
+   *     qualify this type.
+   * @param scaleOrLength for {@code java.sql.JDBCType.DECIMAL} or {@code java.sql.JDBCType.NUMERIC
+   *     types}, this is the number of digits after the decimal point. For Java Object types {@code
+   *     InputStream} and {@code Reader}, this is the length of the data in the stream or reader.
+   *     For all other types, this value will be ignored.
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed {@code
+   *     PreparedStatement} or if the Java Object specified by x is an InputStream or Reader object
+   *     and the value of the scale parameter is less than zero
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void setObject(int parameterIndex, Object x, SQLType targetSqlType, int scaleOrLength)
+      throws SQLException {
+    setInternalObject(
+        parameterIndex,
+        x,
+        targetSqlType == null ? null : targetSqlType.getVendorTypeNumber(),
+        (long) scaleOrLength);
+  }
+
+  /**
+   * Sets the value of the designated parameter with the given object.
+   *
+   * <p>This method is similar to {@link #setObject(int parameterIndex, Object x, SQLType
+   * targetSqlType, int scaleOrLength)}, except that it assumes a scale of zero.
+   *
+   * <p>The default implementation will throw {@code SQLFeatureNotSupportedException}
+   *
+   * @param parameterIndex the first parameter is 1, the second is 2, ...
+   * @param x the object containing the input parameter value
+   * @param targetSqlType the SQL type to be sent to the database
+   * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL
+   *     statement; if a database access error occurs or this method is called on a closed {@code
+   *     PreparedStatement}
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified
+   *     targetSqlType
+   * @see JDBCType
+   * @see SQLType
+   * @since 1.8
+   */
+  @Override
+  public void setObject(int parameterIndex, Object x, SQLType targetSqlType) throws SQLException {
+    setInternalObject(
+        parameterIndex,
+        x,
+        targetSqlType == null ? null : targetSqlType.getVendorTypeNumber(),
+        null);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/CallableParameterMetaData.java b/src/main/java/org/mariadb/jdbc/CallableParameterMetaData.java
new file mode 100644
index 0000000..f9a0f0c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/CallableParameterMetaData.java
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.*;
+import java.util.BitSet;
+import java.util.Locale;
+
+/**
+ * Callable parameter metadata. Server doesn't give detailled information about parameter, so even
+ * if driver return those information, they are not completely accurate.
+ */
+public class CallableParameterMetaData implements java.sql.ParameterMetaData {
+  private final ResultSet rs;
+  private final int parameterCount;
+  private final boolean isFunction;
+
+  /**
+   * Constructor
+   *
+   * @param rs parameter result-set
+   * @param isFunction is command a function or a stored procedure
+   * @throws SQLException if any error occurs
+   */
+  public CallableParameterMetaData(ResultSet rs, boolean isFunction) throws SQLException {
+    this.rs = rs;
+    int count = 0;
+    while (rs.next()) count++;
+    this.parameterCount = count;
+    this.isFunction = isFunction;
+  }
+
+  /**
+   * Retrieves the number of parameters in the <code>PreparedStatement</code> object for which this
+   * <code>ParameterMetaData</code> object contains information.
+   *
+   * @return the number of parameters
+   * @since 1.4
+   */
+  @Override
+  public int getParameterCount() {
+    return parameterCount;
+  }
+
+  /**
+   * Retrieves whether null values are allowed in the designated parameter.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return the nullability status of the given parameter; one of <code>
+   *     ParameterMetaData.parameterNoNulls</code>, <code>ParameterMetaData.parameterNullable</code>
+   *     , or <code>ParameterMetaData.parameterNullableUnknown</code>
+   * @throws SQLException if a database access error occurs
+   * @since 1.4
+   */
+  @Override
+  public int isNullable(int index) throws SQLException {
+    setIndex(index);
+    return ParameterMetaData.parameterNullableUnknown;
+  }
+
+  private void setIndex(int index) throws SQLException {
+    if (index < 1 || index > parameterCount) {
+      throw new SQLException("invalid parameter index " + index);
+    }
+    rs.absolute(index);
+  }
+
+  /**
+   * Retrieves whether values for the designated parameter can be signed numbers.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if a database access error occurs
+   * @since 1.4
+   */
+  @Override
+  public boolean isSigned(int index) throws SQLException {
+    setIndex(index);
+    String paramDetail = rs.getString("DTD_IDENTIFIER");
+    return !paramDetail.contains(" unsigned");
+  }
+
+  /**
+   * Retrieves the designated parameter's specified column size.
+   *
+   * <p>The returned value represents the maximum column size for the given parameter. For numeric
+   * data, this is the maximum precision. For character data, this is the length in characters. For
+   * datetime datatypes, this is the length in characters of the String representation (assuming the
+   * maximum allowed precision of the fractional seconds component). For binary data, this is the
+   * length in bytes. For the ROWID datatype, this is the length in bytes. 0 is returned for data
+   * types where the column size is not applicable.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return precision
+   * @throws SQLException if a database access error occurs
+   */
+  @Override
+  public int getPrecision(int index) throws SQLException {
+    setIndex(index);
+    int characterMaxLength = rs.getInt("CHARACTER_MAXIMUM_LENGTH");
+    int numericPrecision = rs.getInt("NUMERIC_PRECISION");
+    return (numericPrecision > 0) ? numericPrecision : characterMaxLength;
+  }
+
+  /**
+   * Retrieves the designated parameter's number of digits to right of the decimal point. 0 is
+   * returned for data types where the scale is not applicable.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return scale
+   * @throws SQLException if a database access error occurs
+   */
+  @Override
+  public int getScale(int index) throws SQLException {
+    setIndex(index);
+    return rs.getInt("NUMERIC_SCALE");
+  }
+
+  /**
+   * Return the parameter name corresponding to index.
+   *
+   * @param index index
+   * @return parameter name
+   * @throws SQLException if wrong index
+   */
+  public String getParameterName(int index) throws SQLException {
+    setIndex(index);
+    return rs.getString("PARAMETER_NAME");
+  }
+
+  /**
+   * Retrieves the designated parameter's SQL type.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return SQL types from <code>java.sql.Types</code>
+   * @throws SQLException if a database access error occurs
+   * @see Types
+   * @since 1.4
+   */
+  @Override
+  public int getParameterType(int index) throws SQLException {
+    setIndex(index);
+    String str = rs.getString("DATA_TYPE").toUpperCase(Locale.ROOT);
+    switch (str) {
+      case "BIT":
+        return Types.BIT;
+      case "TINYINT":
+        return Types.TINYINT;
+      case "SMALLINT":
+      case "YEAR":
+        return Types.SMALLINT;
+      case "MEDIUMINT":
+      case "INT":
+      case "INT24":
+      case "INTEGER":
+        return Types.INTEGER;
+      case "LONG":
+      case "BIGINT":
+        return Types.BIGINT;
+      case "REAL":
+      case "DOUBLE":
+        return Types.DOUBLE;
+      case "FLOAT":
+        return Types.FLOAT;
+      case "DECIMAL":
+        return Types.DECIMAL;
+      case "CHAR":
+        return Types.CHAR;
+      case "VARCHAR":
+      case "ENUM":
+      case "TINYTEXT":
+      case "SET":
+        return Types.VARCHAR;
+      case "DATE":
+        return Types.DATE;
+      case "TIME":
+        return Types.TIME;
+      case "TIMESTAMP":
+      case "DATETIME":
+        return Types.TIMESTAMP;
+      case "BINARY":
+        return Types.BINARY;
+      case "VARBINARY":
+        return Types.VARBINARY;
+      case "TINYBLOB":
+      case "BLOB":
+      case "MEDIUMBLOB":
+      case "LONGBLOB":
+      case "GEOMETRY":
+        return Types.BLOB;
+      case "TEXT":
+      case "MEDIUMTEXT":
+      case "LONGTEXT":
+        return Types.CLOB;
+      default:
+        return Types.OTHER;
+    }
+  }
+
+  /**
+   * Retrieves the designated parameter's database-specific type name.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return type the name used by the database. If the parameter type is a user-defined type, then
+   *     a fully-qualified type name is returned.
+   * @throws SQLException if a database access error occurs
+   * @since 1.4
+   */
+  @Override
+  public String getParameterTypeName(int index) throws SQLException {
+    setIndex(index);
+    return rs.getString("DATA_TYPE").toUpperCase(Locale.ROOT);
+  }
+
+  /**
+   * Retrieves the fully-qualified name of the Java class whose instances should be passed to the
+   * method <code>PreparedStatement.setObject</code>.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return the fully-qualified name of the class in the Java programming language that would be
+   *     used by the method <code>PreparedStatement.setObject</code> to set the value in the
+   *     specified parameter. This is the class name used for custom mapping.
+   * @throws SQLException if a database access error occurs
+   * @since 1.4
+   */
+  @Override
+  public String getParameterClassName(int index) throws SQLException {
+    setIndex(index);
+    String str = rs.getString("DATA_TYPE").toUpperCase(Locale.ROOT);
+    switch (str) {
+      case "BIT":
+        return BitSet.class.getName();
+      case "TINYINT":
+        return byte.class.getName();
+      case "SMALLINT":
+      case "YEAR":
+        return short.class.getName();
+      case "MEDIUMINT":
+      case "INT":
+      case "INTEGER":
+        return int.class.getName();
+      case "BINARY":
+      case "SET":
+      case "GEOMETRY":
+      case "VARBINARY":
+      case "TINYBLOB":
+        return byte[].class.getName();
+      case "BIGINT":
+        return long.class.getName();
+      case "FLOAT":
+        return float.class.getName();
+      case "DECIMAL":
+        return BigDecimal.class.getName();
+      case "REAL":
+      case "DOUBLE":
+        return double.class.getName();
+      case "CHAR":
+      case "VARCHAR":
+      case "ENUM":
+      case "TINYTEXT":
+        return String.class.getName();
+      case "TEXT":
+      case "MEDIUMTEXT":
+      case "LONGTEXT":
+        return Clob.class.getName();
+
+      case "DATE":
+        return Date.class.getName();
+      case "TIME":
+        return Time.class.getName();
+      case "TIMESTAMP":
+      case "DATETIME":
+        return Timestamp.class.getName();
+      case "BLOB":
+      case "MEDIUMBLOB":
+      case "LONGBLOB":
+        return Blob.class.getName();
+      default:
+        return Object.class.getName();
+    }
+  }
+
+  /**
+   * Retrieves the designated parameter's mode.
+   *
+   * @param index the first parameter is 1, the second is 2, ...
+   * @return mode of the parameter; one of <code>ParameterMetaData.parameterModeIn</code>, <code>
+   *     ParameterMetaData.parameterModeOut</code>, or <code>ParameterMetaData.parameterModeInOut
+   *     </code> <code>ParameterMetaData.parameterModeUnknown</code>.
+   * @throws SQLException if a database access error occurs
+   * @since 1.4
+   */
+  @Override
+  public int getParameterMode(int index) throws SQLException {
+    setIndex(index);
+    if (isFunction) return ParameterMetaData.parameterModeOut;
+    String str = rs.getString("PARAMETER_MODE");
+    switch (str) {
+      case "IN":
+        return ParameterMetaData.parameterModeIn;
+      case "OUT":
+        return ParameterMetaData.parameterModeOut;
+      case "INOUT":
+        return ParameterMetaData.parameterModeInOut;
+      default:
+        return ParameterMetaData.parameterModeUnknown;
+    }
+  }
+
+  /**
+   * Returns an object that implements the given interface to allow access to non-standard methods,
+   * or standard methods not exposed by the proxy.
+   *
+   * <p>If the receiver implements the interface then the result is the receiver or a proxy for the
+   * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the
+   * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of
+   * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If
+   * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException
+   * </code> is thrown.
+   *
+   * @param iface A Class defining an interface that the result must implement.
+   * @return an object that implements the interface. Maybe a proxy for the actual implementing
+   *     object.
+   * @throws SQLException If no object found that implements the interface
+   * @since 1.6
+   */
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
+  }
+
+  /**
+   * Returns true if this either implements the interface argument or is directly or indirectly a
+   * wrapper for an object that does. Returns false otherwise. If this implements the interface then
+   * return true, else if this is a wrapper then return the result of recursively calling <code>
+   * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not
+   * a wrapper, return false. This method should be implemented as a low-cost operation compared to
+   * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>
+   * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same
+   * argument should succeed.
+   *
+   * @param iface a Class defining an interface.
+   * @return true if this implements the interface or directly or indirectly wraps an object that
+   *     does.
+   * @since 1.6
+   */
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/ClientPreparedStatement.java b/src/main/java/org/mariadb/jdbc/ClientPreparedStatement.java
new file mode 100644
index 0000000..683256a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/ClientPreparedStatement.java
@@ -0,0 +1,527 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import static org.mariadb.jdbc.util.constants.Capabilities.*;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.client.result.Result;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.client.*;
+import org.mariadb.jdbc.message.server.OkPacket;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+import org.mariadb.jdbc.util.ClientParser;
+import org.mariadb.jdbc.util.ParameterList;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/**
+ * Client side prepare statement. Question mark will be replaced by escaped parameters, client side
+ */
+public class ClientPreparedStatement extends BasePreparedStatement {
+  private final ClientParser parser;
+
+  /**
+   * Client prepare statement constructor
+   *
+   * @param sql command
+   * @param con connection
+   * @param lock thread safe lock
+   * @param canUseServerTimeout can server use timeout
+   * @param canUseServerMaxRows can server use max rows
+   * @param autoGeneratedKeys must command return automatically generated keys
+   * @param resultSetType resultset type
+   * @param resultSetConcurrency resultset concurrency
+   * @param defaultFetchSize default fetch size
+   */
+  public ClientPreparedStatement(
+      String sql,
+      Connection con,
+      ReentrantLock lock,
+      boolean canUseServerTimeout,
+      boolean canUseServerMaxRows,
+      int autoGeneratedKeys,
+      int resultSetType,
+      int resultSetConcurrency,
+      int defaultFetchSize) {
+    super(
+        sql,
+        con,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        autoGeneratedKeys,
+        resultSetType,
+        resultSetConcurrency,
+        defaultFetchSize);
+
+    boolean noBackslashEscapes =
+        (con.getContext().getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) > 0;
+    parser = ClientParser.parameterParts(sql, noBackslashEscapes);
+    parameters = new ParameterList(parser.getParamCount());
+  }
+
+  /**
+   * use additional part for timeout if possible
+   *
+   * @return pre command for handling timeout
+   */
+  protected String preSqlCmd() {
+    if (queryTimeout != 0 && canUseServerTimeout) {
+      return "SET STATEMENT max_statement_time=" + queryTimeout + " FOR ";
+    }
+    return null;
+  }
+
+  private void executeInternal() throws SQLException {
+    checkNotClosed();
+    validParameters();
+    lock.lock();
+    try {
+      QueryWithParametersPacket query =
+          new QueryWithParametersPacket(preSqlCmd(), parser, parameters, localInfileInputStream);
+      results =
+          con.getClient()
+              .execute(
+                  query,
+                  this,
+                  fetchSize,
+                  maxRows,
+                  resultSetConcurrency,
+                  resultSetType,
+                  closeOnCompletion,
+                  false);
+    } finally {
+      localInfileInputStream = null;
+      lock.unlock();
+    }
+  }
+
+  private void executeInternalPreparedBatch() throws SQLException {
+    checkNotClosed();
+    if (autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS
+        && batchParameters.size() > 1
+        && con.getContext().hasClientCapability(STMT_BULK_OPERATIONS)) {
+      executeBatchBulk();
+    } else {
+      boolean possibleLoadLocal = con.getContext().hasClientCapability(LOCAL_FILES);
+      if (possibleLoadLocal) {
+        String sqlUpper = sql.toUpperCase(Locale.ROOT);
+        possibleLoadLocal =
+            sqlUpper.contains(" LOCAL ")
+                && sqlUpper.contains("LOAD")
+                && sqlUpper.contains(" INFILE");
+      }
+      if (possibleLoadLocal) {
+        executeBatchStd();
+      } else {
+        executeBatchPipeline();
+      }
+    }
+  }
+
+  /**
+   * Send COM_STMT_PREPARE + X * COM_STMT_BULK_EXECUTE, then read for the all answers
+   *
+   * @throws SQLException if IOException / Command error
+   */
+  private void executeBatchBulk() throws SQLException {
+    String cmd = escapeTimeout(sql);
+    try {
+      if (prepareResult == null) {
+        ClientMessage[] packets =
+            new ClientMessage[] {
+              new PreparePacket(cmd), new BulkExecutePacket(null, batchParameters, cmd, null)
+            };
+        List<Completion> res =
+            con.getClient()
+                .executePipeline(
+                    packets,
+                    this,
+                    0,
+                    maxRows,
+                    ResultSet.CONCUR_READ_ONLY,
+                    ResultSet.TYPE_FORWARD_ONLY,
+                    closeOnCompletion,
+                    false);
+        // in case of failover, prepare is done in failover, skipping prepare result
+        if (res.get(0) instanceof PrepareResultPacket) {
+          results = res.subList(1, res.size());
+        } else {
+          results = res;
+        }
+      } else {
+        results =
+            con.getClient()
+                .execute(
+                    new BulkExecutePacket(prepareResult, batchParameters, cmd, null),
+                    this,
+                    fetchSize,
+                    maxRows,
+                    resultSetConcurrency,
+                    resultSetType,
+                    closeOnCompletion,
+                    false);
+      }
+    } catch (SQLException bue) {
+      results = null;
+      throw exceptionFactory()
+          .createBatchUpdate(Collections.emptyList(), batchParameters.size(), bue);
+    }
+  }
+
+  /**
+   * Send n * COM_QUERY + n * read answer
+   *
+   * @throws SQLException if IOException / Command error
+   */
+  private void executeBatchPipeline() throws SQLException {
+    ClientMessage[] packets = new ClientMessage[batchParameters.size()];
+    for (int i = 0; i < batchParameters.size(); i++) {
+      packets[i] = new QueryWithParametersPacket(preSqlCmd(), parser, batchParameters.get(i), null);
+    }
+    try {
+      results =
+          con.getClient()
+              .executePipeline(
+                  packets,
+                  this,
+                  0,
+                  maxRows,
+                  ResultSet.CONCUR_READ_ONLY,
+                  ResultSet.TYPE_FORWARD_ONLY,
+                  closeOnCompletion,
+                  false);
+    } catch (SQLException bue) {
+      results = null;
+      throw bue;
+    }
+  }
+
+  /**
+   * Send n * (COM_QUERY + read answer)
+   *
+   * @throws SQLException if IOException / Command error
+   */
+  private void executeBatchStd() throws SQLException {
+    int i = 0;
+    try {
+      results = new ArrayList<>();
+      for (; i < batchParameters.size(); i++) {
+        results.addAll(
+            con.getClient()
+                .execute(
+                    new QueryWithParametersPacket(
+                        preSqlCmd(), parser, batchParameters.get(i), localInfileInputStream),
+                    this,
+                    0,
+                    maxRows,
+                    ResultSet.CONCUR_READ_ONLY,
+                    ResultSet.TYPE_FORWARD_ONLY,
+                    closeOnCompletion,
+                    false));
+      }
+    } catch (SQLException bue) {
+      BatchUpdateException exception =
+          exceptionFactory().createBatchUpdate(results, batchParameters.size(), bue);
+      results = null;
+      localInfileInputStream = null;
+      throw exception;
+    }
+  }
+
+  /**
+   * Executes the SQL statement in this <code>PreparedStatement</code> object, which may be any kind
+   * of SQL statement. Some prepared statements return multiple results; the <code>execute</code>
+   * method handles these complex statements as well as the simpler form of statements handled by
+   * the methods <code>executeQuery</code> and <code>executeUpdate</code>.
+   *
+   * <p>The <code>execute</code> method returns a <code>boolean</code> to indicate the form of the
+   * first result. You must call either the method <code>getResultSet</code> or <code>getUpdateCount
+   * </code> to retrieve the result; you must call <code>getMoreResults</code> to move to any
+   * subsequent result(s).
+   *
+   * @return <code>true</code> if the first result is a <code>ResultSet</code> object; <code>false
+   *     </code> if the first result is an update count or there is no result
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or an argument is supplied to this method
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @see Statement#execute
+   * @see Statement#getResultSet
+   * @see Statement#getUpdateCount
+   * @see Statement#getMoreResults
+   */
+  @Override
+  public boolean execute() throws SQLException {
+    executeInternal();
+    currResult = results.remove(0);
+    return currResult instanceof Result;
+  }
+
+  /**
+   * Executes the SQL query in this <code>PreparedStatement</code> object and returns the <code>
+   * ResultSet</code> object generated by the query.
+   *
+   * @return a <code>ResultSet</code> object that contains the data produced by the query; never
+   *     <code>null</code>
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or the SQL statement does not return a <code>ResultSet
+   *     </code> object
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   */
+  @Override
+  public ResultSet executeQuery() throws SQLException {
+    executeInternal();
+    currResult = results.remove(0);
+    if (currResult instanceof Result) {
+      return (Result) currResult;
+    }
+    return new CompleteResult(new ColumnDecoder[0], new byte[0][], con.getContext());
+  }
+
+  /**
+   * Executes the SQL statement in this <code>PreparedStatement</code> object, which must be an SQL
+   * Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+   * <code>DELETE</code>; or an SQL statement that returns nothing, such as a DDL statement.
+   *
+   * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0
+   *     for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or the SQL statement returns a <code>ResultSet</code> object
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   */
+  @Override
+  public int executeUpdate() throws SQLException {
+    return (int) executeLargeUpdate();
+  }
+
+  /**
+   * Executes the SQL statement in this <code>PreparedStatement</code> object, which must be an SQL
+   * Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+   * <code>DELETE</code>; or an SQL statement that returns nothing, such as a DDL statement.
+   *
+   * <p>This method should be used when the returned row count may exceed {@link Integer#MAX_VALUE}.
+   *
+   * <p>The default implementation will throw {@code UnsupportedOperationException}
+   *
+   * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0
+   *     for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or the SQL statement returns a <code>ResultSet</code> object
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @since 1.8
+   */
+  @Override
+  public long executeLargeUpdate() throws SQLException {
+    executeInternal();
+    currResult = results.remove(0);
+    if (currResult instanceof Result) {
+      throw exceptionFactory()
+          .create("the given SQL statement produces an unexpected ResultSet object", "HY000");
+    }
+    return ((OkPacket) currResult).getAffectedRows();
+  }
+
+  private ExceptionFactory exceptionFactory() {
+    return con.getExceptionFactory().of(this);
+  }
+
+  /**
+   * Adds a set of parameters to this <code>PreparedStatement</code> object's batch of commands.
+   *
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>PreparedStatement</code>
+   * @see Statement#addBatch
+   * @since 1.2
+   */
+  @Override
+  public void addBatch() throws SQLException {
+    validParameters();
+    if (batchParameters == null) batchParameters = new ArrayList<>();
+    batchParameters.add(parameters);
+    parameters = parameters.clone();
+  }
+
+  /**
+   * Validate parameter number according to expected parameter.
+   *
+   * @throws SQLException if doesn't correspond
+   */
+  protected void validParameters() throws SQLException {
+    for (int i = 0; i < parser.getParamCount(); i++) {
+      if (!parameters.containsKey(i)) {
+        throw exceptionFactory()
+            .create("Parameter at position " + (i + 1) + " is not set", "07004");
+      }
+    }
+  }
+
+  @Override
+  public void setQueryTimeout(int seconds) throws SQLException {
+    super.setQueryTimeout(seconds);
+    if (canUseServerTimeout && prepareResult != null) {
+      prepareResult.close(con.getClient());
+      prepareResult = null;
+    }
+  }
+
+  @Override
+  public void setMaxRows(int max) throws SQLException {
+    super.setMaxRows(max);
+    if (canUseServerMaxRows && prepareResult != null) {
+      prepareResult.close(con.getClient());
+      prepareResult = null;
+    }
+  }
+
+  @Override
+  public void setLargeMaxRows(long max) throws SQLException {
+    super.setLargeMaxRows(max);
+    if (canUseServerMaxRows && prepareResult != null) {
+      prepareResult.close(con.getClient());
+      prepareResult = null;
+    }
+  }
+
+  /**
+   * Retrieves a <code>ResultSetMetaData</code> object that contains information about the columns
+   * of the <code>ResultSet</code> object that will be returned when this <code>PreparedStatement
+   * </code> object is executed.
+   *
+   * <p>Because a <code>PreparedStatement</code> object is precompiled, it is possible to know about
+   * the <code>ResultSet</code> object that it will return without having to execute it.
+   * Consequently, it is possible to invoke the method <code>getMetaData</code> on a <code>
+   * PreparedStatement</code> object rather than waiting to execute it and then invoking the <code>
+   * ResultSet.getMetaData</code> method on the <code>ResultSet</code> object that is returned.
+   *
+   * <p><B>NOTE:</B> Using this method may be expensive for some drivers due to the lack of
+   * underlying DBMS support.
+   *
+   * @return the description of a <code>ResultSet</code> object's columns or <code>null</code> if
+   *     the driver cannot return a <code>ResultSetMetaData</code> object
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public ResultSetMetaData getMetaData() throws SQLException {
+
+    // send COM_STMT_PREPARE
+    if (prepareResult == null)
+      con.getClient().execute(new PreparePacket(escapeTimeout(sql)), this, true);
+    return new org.mariadb.jdbc.client.result.ResultSetMetaData(
+        exceptionFactory(), prepareResult.getColumns(), con.getContext().getConf(), false);
+  }
+
+  /**
+   * Retrieves the number, types and properties of this <code>PreparedStatement</code> object's
+   * parameters.
+   *
+   * @return a <code>ParameterMetaData</code> object that contains information about the number,
+   *     types and properties for each parameter marker of this <code>PreparedStatement</code>
+   *     object
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>PreparedStatement</code>
+   * @see ParameterMetaData
+   * @since 1.4
+   */
+  @Override
+  public java.sql.ParameterMetaData getParameterMetaData() throws SQLException {
+    // send COM_STMT_PREPARE
+    if (prepareResult == null) {
+      try {
+        con.getClient().execute(new PreparePacket(escapeTimeout(sql)), this, true);
+      } catch (SQLException e) {
+        return new SimpleParameterMetaData(exceptionFactory(), parser.getParamCount());
+      }
+    }
+    return new ParameterMetaData(exceptionFactory(), prepareResult.getParameters());
+  }
+
+  @Override
+  public int[] executeBatch() throws SQLException {
+    checkNotClosed();
+    if (batchParameters == null || batchParameters.isEmpty()) return new int[0];
+    lock.lock();
+    try {
+      executeInternalPreparedBatch();
+      int[] updates = new int[batchParameters.size()];
+      if (results.size() != batchParameters.size()) {
+        for (int i = 0; i < batchParameters.size(); i++) {
+          updates[i] = Statement.SUCCESS_NO_INFO;
+        }
+      } else {
+        for (int i = 0; i < updates.length; i++) {
+          if (results.get(i) instanceof OkPacket) {
+            updates[i] = (int) ((OkPacket) results.get(i)).getAffectedRows();
+          } else {
+            updates[i] = org.mariadb.jdbc.Statement.SUCCESS_NO_INFO;
+          }
+        }
+      }
+      currResult = results.remove(0);
+      return updates;
+    } finally {
+      batchParameters.clear();
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public long[] executeLargeBatch() throws SQLException {
+    checkNotClosed();
+    if (batchParameters == null || batchParameters.isEmpty()) return new long[0];
+    lock.lock();
+    try {
+      executeInternalPreparedBatch();
+      long[] updates = new long[results.size()];
+      for (int i = 0; i < results.size(); i++) {
+        updates[i] = ((OkPacket) results.get(i)).getAffectedRows();
+      }
+      currResult = results.remove(0);
+      return updates;
+
+    } finally {
+      batchParameters.clear();
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public void close() throws SQLException {
+    if (prepareResult != null) {
+      lock.lock();
+      try {
+        prepareResult.close(this.con.getClient());
+      } finally {
+        lock.unlock();
+      }
+    }
+    con.fireStatementClosed(this);
+    super.close();
+  }
+
+  @Override
+  public String toString() {
+    return "ClientPreparedStatement{" + super.toString() + '}';
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/Configuration.java b/src/main/java/org/mariadb/jdbc/Configuration.java
new file mode 100644
index 0000000..8388b6c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/Configuration.java
@@ -0,0 +1,2690 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.*;
+import org.mariadb.jdbc.export.HaMode;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+import org.mariadb.jdbc.plugin.credential.CredentialPluginLoader;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+import org.mariadb.jdbc.util.options.OptionAliases;
+
+/**
+ * parse and verification of URL.
+ *
+ * <p>basic syntax :<br>
+ * {@code
+ * jdbc:mariadb:[replication:|failover|loadbalance:|aurora:]//<hostDescription>[,<hostDescription>]/[database>]
+ * [?<key1>=<value1>[&<key2>=<value2>]] }
+ *
+ * <p>hostDescription:<br>
+ * - simple :<br>
+ * {@code <host>:<portnumber>}<br>
+ * (for example localhost:3306)<br>
+ * <br>
+ * - complex :<br>
+ * {@code address=[(type=(master|slave))][(port=<portnumber>)](host=<host>)}<br>
+ * <br>
+ * <br>
+ * type is by default master<br>
+ * port is by default 3306<br>
+ *
+ * <p>host can be dns name, ipv4 or ipv6.<br>
+ * in case of ipv6 and simple host description, the ip must be written inside bracket.<br>
+ * exemple : {@code jdbc:mariadb://[2001:0660:7401:0200:0000:0000:0edf:bdd7]:3306}<br>
+ *
+ * <p>Some examples :<br>
+ * {@code jdbc:mariadb://localhost:3306/database?user=greg&password=pass}<br>
+ * {@code
+ * jdbc:mariadb://address=(type=master)(host=master1),address=(port=3307)(type=slave)(host=slave1)/database?user=greg&password=pass}
+ * <br>
+ */
+public class Configuration {
+  private static final Logger logger = Loggers.getLogger(Configuration.class);
+
+  // standard options
+  private String user = null;
+  private String password = null;
+  private String database = null;
+  private List<HostAddress> addresses = null;
+  private HaMode haMode = HaMode.NONE;
+
+  private String initialUrl = null;
+  private Properties nonMappedOptions = null;
+
+  // various
+  private String timezone = null;
+  private Boolean autocommit = null;
+  private boolean useMysqlMetadata = false;
+  private boolean createDatabaseIfNotExist = false;
+  private TransactionIsolation transactionIsolation = null;
+  private int defaultFetchSize = 0;
+  private int maxQuerySizeToLog = 1024;
+  private Integer maxAllowedPacket = null;
+  private String geometryDefaultType = null;
+  private String restrictedAuth = null;
+  private String initSql = null;
+
+  // socket
+  private String socketFactory = null;
+  private int connectTimeout =
+      DriverManager.getLoginTimeout() > 0 ? DriverManager.getLoginTimeout() * 1000 : 30_000;
+  private String pipe = null;
+  private String localSocket = null;
+  private boolean uuidAsString = false;
+  private boolean tcpKeepAlive = true;
+  private int tcpKeepIdle = 0;
+  private int tcpKeepCount = 0;
+  private int tcpKeepInterval = 0;
+  private boolean tcpAbortiveClose = false;
+  private String localSocketAddress = null;
+  private int socketTimeout = 0;
+  private boolean useReadAheadInput = false;
+  private String tlsSocketType = null;
+
+  // SSL
+  private SslMode sslMode = SslMode.DISABLE;
+  private String serverSslCert = null;
+  private String keyStore = null;
+  private String keyStorePassword = null;
+  private String keyStoreType = null;
+  private String enabledSslCipherSuites = null;
+  private String enabledSslProtocolSuites = null;
+
+  // protocol
+  private boolean allowMultiQueries = false;
+  private boolean allowLocalInfile = true;
+  private boolean useCompression = false;
+  private boolean useAffectedRows = false;
+  private boolean useBulkStmts = true;
+  private boolean disablePipeline = false;
+  // prepare
+  private boolean cachePrepStmts = true;
+  private int prepStmtCacheSize = 250;
+  private boolean useServerPrepStmts = false;
+
+  // authentication
+  private CredentialPlugin credentialType = null;
+  private String sessionVariables = null;
+  private String connectionAttributes = null;
+  private String servicePrincipalName = null;
+
+  // meta
+  private boolean blankTableNameMeta = false;
+  private boolean tinyInt1isBit = true;
+  private boolean transformedBitIsBoolean = true;
+  private boolean yearIsDateType = true;
+  private boolean dumpQueriesOnException = false;
+  private boolean includeInnodbStatusInDeadlockExceptions = false;
+  private boolean includeThreadDumpInDeadlockExceptions = false;
+
+  // HA options
+  private int retriesAllDown = 120;
+  private String galeraAllowedState = null;
+  private boolean transactionReplay = false;
+  private int transactionReplaySize = 64;
+
+  // Pool options
+  private boolean pool = false;
+  private String poolName = null;
+  private int maxPoolSize = 8;
+  private int minPoolSize = 8;
+  private int maxIdleTime = 600_000;
+  private boolean registerJmxPool = true;
+  private int poolValidMinDelay = 1000;
+  private boolean useResetConnection = false;
+
+  // MySQL sha authentication
+  private String serverRsaPublicKeyFile = null;
+  private boolean allowPublicKeyRetrieval = false;
+
+  private Codec<?>[] codecs = null;
+
+  private Configuration() {}
+
+  private Configuration(
+      String user,
+      String password,
+      String database,
+      List<HostAddress> addresses,
+      HaMode haMode,
+      Properties nonMappedOptions,
+      String timezone,
+      Boolean autocommit,
+      boolean useMysqlMetadata,
+      boolean createDatabaseIfNotExist,
+      TransactionIsolation transactionIsolation,
+      int defaultFetchSize,
+      int maxQuerySizeToLog,
+      Integer maxAllowedPacket,
+      String geometryDefaultType,
+      String restrictedAuth,
+      String initSql,
+      String socketFactory,
+      int connectTimeout,
+      String pipe,
+      String localSocket,
+      boolean tcpKeepAlive,
+      boolean uuidAsString,
+      int tcpKeepIdle,
+      int tcpKeepCount,
+      int tcpKeepInterval,
+      boolean tcpAbortiveClose,
+      String localSocketAddress,
+      int socketTimeout,
+      boolean useReadAheadInput,
+      String tlsSocketType,
+      SslMode sslMode,
+      String serverSslCert,
+      String keyStore,
+      String keyStorePassword,
+      String keyStoreType,
+      String enabledSslCipherSuites,
+      String enabledSslProtocolSuites,
+      boolean allowMultiQueries,
+      boolean allowLocalInfile,
+      boolean useCompression,
+      boolean useAffectedRows,
+      boolean useBulkStmts,
+      boolean disablePipeline,
+      boolean cachePrepStmts,
+      int prepStmtCacheSize,
+      boolean useServerPrepStmts,
+      CredentialPlugin credentialType,
+      String sessionVariables,
+      String connectionAttributes,
+      String servicePrincipalName,
+      boolean blankTableNameMeta,
+      boolean tinyInt1isBit,
+      boolean transformedBitIsBoolean,
+      boolean yearIsDateType,
+      boolean dumpQueriesOnException,
+      boolean includeInnodbStatusInDeadlockExceptions,
+      boolean includeThreadDumpInDeadlockExceptions,
+      int retriesAllDown,
+      String galeraAllowedState,
+      boolean transactionReplay,
+      int transactionReplaySize,
+      boolean pool,
+      String poolName,
+      int maxPoolSize,
+      int minPoolSize,
+      int maxIdleTime,
+      boolean registerJmxPool,
+      int poolValidMinDelay,
+      boolean useResetConnection,
+      String serverRsaPublicKeyFile,
+      boolean allowPublicKeyRetrieval) {
+    this.user = user;
+    this.password = password;
+    this.database = database;
+    this.addresses = addresses;
+    this.haMode = haMode;
+    this.nonMappedOptions = nonMappedOptions;
+    this.timezone = timezone;
+    this.autocommit = autocommit;
+    this.useMysqlMetadata = useMysqlMetadata;
+    this.createDatabaseIfNotExist = createDatabaseIfNotExist;
+    this.transactionIsolation = transactionIsolation;
+    this.defaultFetchSize = defaultFetchSize;
+    this.maxQuerySizeToLog = maxQuerySizeToLog;
+    this.maxAllowedPacket = maxAllowedPacket;
+    this.geometryDefaultType = geometryDefaultType;
+    this.restrictedAuth = restrictedAuth;
+    this.initSql = initSql;
+    this.socketFactory = socketFactory;
+    this.connectTimeout = connectTimeout;
+    this.pipe = pipe;
+    this.localSocket = localSocket;
+    this.tcpKeepAlive = tcpKeepAlive;
+    this.uuidAsString = uuidAsString;
+    this.tcpKeepIdle = tcpKeepIdle;
+    this.tcpKeepCount = tcpKeepCount;
+    this.tcpKeepInterval = tcpKeepInterval;
+    this.tcpAbortiveClose = tcpAbortiveClose;
+    this.localSocketAddress = localSocketAddress;
+    this.socketTimeout = socketTimeout;
+    this.useReadAheadInput = useReadAheadInput;
+    this.tlsSocketType = tlsSocketType;
+    this.sslMode = sslMode;
+    this.serverSslCert = serverSslCert;
+    this.keyStore = keyStore;
+    this.keyStorePassword = keyStorePassword;
+    this.keyStoreType = keyStoreType;
+    this.enabledSslCipherSuites = enabledSslCipherSuites;
+    this.enabledSslProtocolSuites = enabledSslProtocolSuites;
+    this.allowMultiQueries = allowMultiQueries;
+    this.allowLocalInfile = allowLocalInfile;
+    this.useCompression = useCompression;
+    this.useAffectedRows = useAffectedRows;
+    this.useBulkStmts = useBulkStmts;
+    this.disablePipeline = disablePipeline;
+    this.cachePrepStmts = cachePrepStmts;
+    this.prepStmtCacheSize = prepStmtCacheSize;
+    this.useServerPrepStmts = useServerPrepStmts;
+    this.credentialType = credentialType;
+    this.sessionVariables = sessionVariables;
+    this.connectionAttributes = connectionAttributes;
+    this.servicePrincipalName = servicePrincipalName;
+    this.blankTableNameMeta = blankTableNameMeta;
+    this.tinyInt1isBit = tinyInt1isBit;
+    this.transformedBitIsBoolean = transformedBitIsBoolean;
+    this.yearIsDateType = yearIsDateType;
+    this.dumpQueriesOnException = dumpQueriesOnException;
+    this.includeInnodbStatusInDeadlockExceptions = includeInnodbStatusInDeadlockExceptions;
+    this.includeThreadDumpInDeadlockExceptions = includeThreadDumpInDeadlockExceptions;
+    this.retriesAllDown = retriesAllDown;
+    this.galeraAllowedState = galeraAllowedState;
+    this.transactionReplay = transactionReplay;
+    this.transactionReplaySize = transactionReplaySize;
+    this.pool = pool;
+    this.poolName = poolName;
+    this.maxPoolSize = maxPoolSize;
+    this.minPoolSize = minPoolSize;
+    this.maxIdleTime = maxIdleTime;
+    this.registerJmxPool = registerJmxPool;
+    this.poolValidMinDelay = poolValidMinDelay;
+    this.useResetConnection = useResetConnection;
+    this.serverRsaPublicKeyFile = serverRsaPublicKeyFile;
+    this.allowPublicKeyRetrieval = allowPublicKeyRetrieval;
+    this.initialUrl = buildUrl(this);
+  }
+
+  private Configuration(
+      String database,
+      List<HostAddress> addresses,
+      HaMode haMode,
+      String user,
+      String password,
+      String enabledSslProtocolSuites,
+      String socketFactory,
+      Integer connectTimeout,
+      String pipe,
+      String localSocket,
+      Boolean tcpKeepAlive,
+      Boolean uuidAsString,
+      Integer tcpKeepIdle,
+      Integer tcpKeepCount,
+      Integer tcpKeepInterval,
+      Boolean tcpAbortiveClose,
+      String localSocketAddress,
+      Integer socketTimeout,
+      Boolean allowMultiQueries,
+      Boolean allowLocalInfile,
+      Boolean useCompression,
+      Boolean blankTableNameMeta,
+      String credentialType,
+      String sslMode,
+      String transactionIsolation,
+      String enabledSslCipherSuites,
+      String sessionVariables,
+      Boolean tinyInt1isBit,
+      Boolean transformedBitIsBoolean,
+      Boolean yearIsDateType,
+      String timezone,
+      Boolean dumpQueriesOnException,
+      Integer prepStmtCacheSize,
+      Boolean useAffectedRows,
+      Boolean useServerPrepStmts,
+      String connectionAttributes,
+      Boolean useBulkStmts,
+      Boolean disablePipeline,
+      Boolean autocommit,
+      Boolean useMysqlMetadata,
+      Boolean createDatabaseIfNotExist,
+      Boolean includeInnodbStatusInDeadlockExceptions,
+      Boolean includeThreadDumpInDeadlockExceptions,
+      String servicePrincipalName,
+      Integer defaultFetchSize,
+      String tlsSocketType,
+      Integer maxQuerySizeToLog,
+      Integer maxAllowedPacket,
+      Integer retriesAllDown,
+      String galeraAllowedState,
+      Boolean pool,
+      String poolName,
+      Integer maxPoolSize,
+      Integer minPoolSize,
+      Integer maxIdleTime,
+      Boolean registerJmxPool,
+      Integer poolValidMinDelay,
+      Boolean useResetConnection,
+      String serverRsaPublicKeyFile,
+      Boolean allowPublicKeyRetrieval,
+      String serverSslCert,
+      String keyStore,
+      String keyStorePassword,
+      String keyStoreType,
+      Boolean useReadAheadInput,
+      Boolean cachePrepStmts,
+      Boolean transactionReplay,
+      Integer transactionReplaySize,
+      String geometryDefaultType,
+      String restrictedAuth,
+      String initSql,
+      Properties nonMappedOptions)
+      throws SQLException {
+    this.database = database;
+    this.addresses = addresses;
+    this.nonMappedOptions = nonMappedOptions;
+    if (haMode != null) this.haMode = haMode;
+    this.credentialType = CredentialPluginLoader.get(credentialType);
+    this.user = user;
+    this.password = password;
+    this.enabledSslProtocolSuites = enabledSslProtocolSuites;
+    this.socketFactory = socketFactory;
+    if (connectTimeout != null) this.connectTimeout = connectTimeout;
+    this.pipe = pipe;
+    this.localSocket = localSocket;
+    if (tcpKeepAlive != null) this.tcpKeepAlive = tcpKeepAlive;
+    if (uuidAsString != null) this.uuidAsString = uuidAsString;
+    if (tcpKeepIdle != null) this.tcpKeepIdle = tcpKeepIdle;
+    if (tcpKeepCount != null) this.tcpKeepCount = tcpKeepCount;
+    if (tcpKeepInterval != null) this.tcpKeepInterval = tcpKeepInterval;
+    if (tcpAbortiveClose != null) this.tcpAbortiveClose = tcpAbortiveClose;
+    this.localSocketAddress = localSocketAddress;
+    if (socketTimeout != null) this.socketTimeout = socketTimeout;
+    if (allowMultiQueries != null) this.allowMultiQueries = allowMultiQueries;
+    if (allowLocalInfile != null) this.allowLocalInfile = allowLocalInfile;
+    if (useCompression != null) this.useCompression = useCompression;
+    if (blankTableNameMeta != null) this.blankTableNameMeta = blankTableNameMeta;
+    if (this.credentialType != null
+        && this.credentialType.mustUseSsl()
+        && (sslMode == null || SslMode.from(sslMode) == SslMode.DISABLE)) {
+      this.sslMode = SslMode.VERIFY_FULL;
+    } else {
+      this.sslMode = sslMode != null ? SslMode.from(sslMode) : SslMode.DISABLE;
+    }
+    if (transactionIsolation != null)
+      this.transactionIsolation = TransactionIsolation.from(transactionIsolation);
+    this.enabledSslCipherSuites = enabledSslCipherSuites;
+    this.sessionVariables = sessionVariables;
+    if (tinyInt1isBit != null) this.tinyInt1isBit = tinyInt1isBit;
+    if (transformedBitIsBoolean != null) this.transformedBitIsBoolean = transformedBitIsBoolean;
+    if (yearIsDateType != null) this.yearIsDateType = yearIsDateType;
+    this.timezone = timezone;
+    if (dumpQueriesOnException != null) this.dumpQueriesOnException = dumpQueriesOnException;
+    if (prepStmtCacheSize != null) this.prepStmtCacheSize = prepStmtCacheSize;
+    if (useAffectedRows != null) this.useAffectedRows = useAffectedRows;
+    if (useServerPrepStmts != null) this.useServerPrepStmts = useServerPrepStmts;
+    this.connectionAttributes = connectionAttributes;
+    if (useBulkStmts != null) this.useBulkStmts = useBulkStmts;
+    if (disablePipeline != null) this.disablePipeline = disablePipeline;
+    if (autocommit != null) this.autocommit = autocommit;
+    if (useMysqlMetadata != null) this.useMysqlMetadata = useMysqlMetadata;
+    if (createDatabaseIfNotExist != null) this.createDatabaseIfNotExist = createDatabaseIfNotExist;
+    if (includeInnodbStatusInDeadlockExceptions != null)
+      this.includeInnodbStatusInDeadlockExceptions = includeInnodbStatusInDeadlockExceptions;
+    if (includeThreadDumpInDeadlockExceptions != null)
+      this.includeThreadDumpInDeadlockExceptions = includeThreadDumpInDeadlockExceptions;
+    if (servicePrincipalName != null) this.servicePrincipalName = servicePrincipalName;
+    if (defaultFetchSize != null) this.defaultFetchSize = defaultFetchSize;
+    if (tlsSocketType != null) this.tlsSocketType = tlsSocketType;
+    if (maxQuerySizeToLog != null) this.maxQuerySizeToLog = maxQuerySizeToLog;
+    if (maxAllowedPacket != null) this.maxAllowedPacket = maxAllowedPacket;
+    if (retriesAllDown != null) this.retriesAllDown = retriesAllDown;
+    if (galeraAllowedState != null) this.galeraAllowedState = galeraAllowedState;
+    if (pool != null) this.pool = pool;
+    if (poolName != null) this.poolName = poolName;
+    if (maxPoolSize != null) this.maxPoolSize = maxPoolSize;
+    // if min pool size default to maximum pool size if not set
+    if (minPoolSize != null) {
+      this.minPoolSize = minPoolSize;
+    } else {
+      this.minPoolSize = this.maxPoolSize;
+    }
+
+    if (maxIdleTime != null) this.maxIdleTime = maxIdleTime;
+    if (registerJmxPool != null) this.registerJmxPool = registerJmxPool;
+    if (poolValidMinDelay != null) this.poolValidMinDelay = poolValidMinDelay;
+    if (useResetConnection != null) this.useResetConnection = useResetConnection;
+    if (serverRsaPublicKeyFile != null) this.serverRsaPublicKeyFile = serverRsaPublicKeyFile;
+    if (allowPublicKeyRetrieval != null) this.allowPublicKeyRetrieval = allowPublicKeyRetrieval;
+    if (useReadAheadInput != null) this.useReadAheadInput = useReadAheadInput;
+    if (cachePrepStmts != null) this.cachePrepStmts = cachePrepStmts;
+    if (transactionReplay != null) this.transactionReplay = transactionReplay;
+    if (transactionReplaySize != null) this.transactionReplaySize = transactionReplaySize;
+    if (geometryDefaultType != null) this.geometryDefaultType = geometryDefaultType;
+    if (restrictedAuth != null) this.restrictedAuth = restrictedAuth;
+    if (initSql != null) this.initSql = initSql;
+    if (serverSslCert != null) this.serverSslCert = serverSslCert;
+    if (keyStore != null) this.keyStore = keyStore;
+    if (keyStorePassword != null) this.keyStorePassword = keyStorePassword;
+    if (keyStoreType != null) this.keyStoreType = keyStoreType;
+
+    // *************************************************************
+    // host primary check
+    // *************************************************************
+    boolean first = true;
+    for (HostAddress host : addresses) {
+      boolean primary = haMode != HaMode.REPLICATION || first;
+      if (host.primary == null) {
+        host.primary = primary;
+      }
+      first = false;
+    }
+
+    // *************************************************************
+    // option value verification
+    // *************************************************************
+
+    // int fields must all be positive
+    Field[] fields = Configuration.class.getDeclaredFields();
+    try {
+      for (Field field : fields) {
+        if (field.getType().equals(int.class)) {
+          int val = field.getInt(this);
+          if (val < 0) {
+            throw new SQLException(
+                String.format("Value for %s must be >= 1 (value is %s)", field.getName(), val));
+          }
+        }
+      }
+    } catch (IllegalArgumentException | IllegalAccessException ie) {
+      // eat
+    }
+  }
+
+  /**
+   * Tell if mariadb driver accept url string. (Correspond to interface
+   * java.jdbc.Driver.acceptsURL() method)
+   *
+   * @param url url String
+   * @return true if url string correspond.
+   */
+  public static boolean acceptsUrl(String url) {
+    return url != null
+        && (url.startsWith("jdbc:mariadb:")
+            || (url.startsWith("jdbc:mysql:") && url.contains("permitMysqlScheme")));
+  }
+
+  /**
+   * parse connection string
+   *
+   * @param url connection string
+   * @return configuration resulting object
+   * @throws SQLException if not supported driver or wrong connection string format.
+   */
+  public static Configuration parse(final String url) throws SQLException {
+    return parse(url, new Properties());
+  }
+
+  /**
+   * Parse url connection string with additional properties.
+   *
+   * @param url connection string
+   * @param prop properties
+   * @return UrlParser instance
+   * @throws SQLException if parsing exception occur
+   */
+  public static Configuration parse(final String url, Properties prop) throws SQLException {
+    if (acceptsUrl(url)) {
+      return parseInternal(url, (prop == null) ? new Properties() : prop);
+    }
+    return null;
+  }
+
+  /**
+   * Parses the connection URL in order to set the UrlParser instance with all the information
+   * provided through the URL.
+   *
+   * @param url connection URL
+   * @param properties properties
+   * @throws SQLException if format is incorrect
+   */
+  private static Configuration parseInternal(String url, Properties properties)
+      throws SQLException {
+    try {
+      Builder builder = new Builder();
+      int separator = url.indexOf("//");
+      if (separator == -1) {
+        throw new IllegalArgumentException(
+            "url parsing error : '//' is not present in the url " + url);
+      }
+      builder.haMode(parseHaMode(url, separator));
+
+      String urlSecondPart = url.substring(separator + 2);
+      int dbIndex = urlSecondPart.indexOf("/");
+      int paramIndex = urlSecondPart.indexOf("?");
+
+      String hostAddressesString;
+      String additionalParameters;
+      if ((dbIndex < paramIndex && dbIndex < 0) || (dbIndex > paramIndex && paramIndex > -1)) {
+        hostAddressesString = urlSecondPart.substring(0, paramIndex);
+        additionalParameters = urlSecondPart.substring(paramIndex);
+      } else if (dbIndex < paramIndex || dbIndex > paramIndex) {
+        hostAddressesString = urlSecondPart.substring(0, dbIndex);
+        additionalParameters = urlSecondPart.substring(dbIndex);
+      } else {
+        hostAddressesString = urlSecondPart;
+        additionalParameters = null;
+      }
+
+      if (additionalParameters != null) {
+        int optIndex = additionalParameters.indexOf("?");
+        String database;
+        if (optIndex < 0) {
+          database = (additionalParameters.length() > 1) ? additionalParameters.substring(1) : null;
+        } else {
+          if (optIndex == 0) {
+            database = null;
+          } else {
+            database = additionalParameters.substring(1, optIndex);
+            if (database.isEmpty()) database = null;
+          }
+          String urlParameters = additionalParameters.substring(optIndex + 1);
+          if (urlParameters != null && !urlParameters.isEmpty()) {
+            String[] parameters = urlParameters.split("&");
+            for (String parameter : parameters) {
+              int pos = parameter.indexOf('=');
+              if (pos == -1) {
+                properties.setProperty(parameter, "");
+              } else {
+                properties.setProperty(parameter.substring(0, pos), parameter.substring(pos + 1));
+              }
+            }
+          }
+        }
+        builder.database(database);
+      } else {
+        builder.database(null);
+      }
+
+      mapPropertiesToOption(builder, properties);
+      builder._addresses = HostAddress.parse(hostAddressesString, builder._haMode);
+      return builder.build();
+
+    } catch (IllegalArgumentException i) {
+      throw new SQLException("error parsing url : " + i.getMessage(), i);
+    }
+  }
+
+  private static void mapPropertiesToOption(Builder builder, Properties properties) {
+    Properties nonMappedOptions = new Properties();
+
+    try {
+      // Option object is already initialized to default values.
+      // loop on properties,
+      // - check DefaultOption to check that property value correspond to type (and range)
+      // - set values
+      for (final Object keyObj : properties.keySet()) {
+        String realKey =
+            OptionAliases.OPTIONS_ALIASES.get(keyObj.toString().toLowerCase(Locale.ROOT));
+        if (realKey == null) realKey = keyObj.toString();
+        final Object propertyValue = properties.get(keyObj);
+        if (propertyValue != null && realKey != null) {
+          boolean used = false;
+          for (Field field : Builder.class.getDeclaredFields()) {
+            if (realKey.toLowerCase(Locale.ROOT).equals(field.getName().toLowerCase(Locale.ROOT))) {
+              field.setAccessible(true);
+              used = true;
+
+              if (field.getGenericType().equals(String.class)
+                  && !propertyValue.toString().isEmpty()) {
+                field.set(builder, propertyValue);
+              } else if (field.getGenericType().equals(Boolean.class)) {
+                switch (propertyValue.toString().toLowerCase()) {
+                  case "":
+                  case "1":
+                  case "true":
+                    field.set(builder, Boolean.TRUE);
+                    break;
+
+                  case "0":
+                  case "false":
+                    field.set(builder, Boolean.FALSE);
+                    break;
+
+                  default:
+                    throw new IllegalArgumentException(
+                        String.format(
+                            "Optional parameter %s must be boolean (true/false or 0/1) was '%s'",
+                            keyObj, propertyValue));
+                }
+              } else if (field.getGenericType().equals(Integer.class)) {
+                try {
+                  final Integer value = Integer.parseInt(propertyValue.toString());
+                  field.set(builder, value);
+                } catch (NumberFormatException n) {
+                  throw new IllegalArgumentException(
+                      String.format(
+                          "Optional parameter %s must be Integer, was '%s'",
+                          keyObj, propertyValue));
+                }
+              }
+            }
+          }
+          if (!used) nonMappedOptions.put(realKey, propertyValue);
+        }
+      }
+
+      // for compatibility with 2.x
+      if (isSet("useSsl", nonMappedOptions) || isSet("useSSL", nonMappedOptions)) {
+        Properties deprecatedDesc = new Properties();
+        try (InputStream inputStream =
+            Driver.class.getClassLoader().getResourceAsStream("deprecated.properties")) {
+          deprecatedDesc.load(inputStream);
+        } catch (IOException io) {
+          // eat
+        }
+        logger.warn(deprecatedDesc.getProperty("useSsl"));
+        if (isSet("trustServerCertificate", nonMappedOptions)) {
+          builder.sslMode("trust");
+          logger.warn(deprecatedDesc.getProperty("trustServerCertificate"));
+        } else if (isSet("disableSslHostnameVerification", nonMappedOptions)) {
+          logger.warn(deprecatedDesc.getProperty("disableSslHostnameVerification"));
+          builder.sslMode("verify-ca");
+        } else {
+          builder.sslMode("verify-full");
+        }
+      }
+    } catch (IllegalAccessException | SecurityException s) {
+      throw new IllegalArgumentException("Unexpected error", s);
+    }
+    builder._nonMappedOptions = nonMappedOptions;
+  }
+
+  private static boolean isSet(String key, Properties nonMappedOptions) {
+    String value = nonMappedOptions.getProperty(key);
+    return value != null && (value.equals("1") || value.equals("true") || value.isEmpty());
+  }
+
+  private static HaMode parseHaMode(String url, int separator) {
+    // parser is sure to have at least 2 colon, since jdbc:[mysql|mariadb]: is tested.
+    int firstColonPos = url.indexOf(':');
+    int secondColonPos = url.indexOf(':', firstColonPos + 1);
+    int thirdColonPos = url.indexOf(':', secondColonPos + 1);
+
+    if (thirdColonPos > separator || thirdColonPos == -1) {
+      if (secondColonPos == separator - 1) {
+        return HaMode.NONE;
+      }
+      thirdColonPos = separator;
+    }
+
+    try {
+      String haModeString = url.substring(secondColonPos + 1, thirdColonPos);
+      if ("FAILOVER".equalsIgnoreCase(haModeString)) {
+        haModeString = "LOADBALANCE";
+      }
+      return HaMode.from(haModeString);
+    } catch (IllegalArgumentException i) {
+      throw new IllegalArgumentException(
+          "wrong failover parameter format in connection String " + url);
+    }
+  }
+
+  /**
+   * Clone configuration with another user/password
+   *
+   * @param username new username
+   * @param password new password
+   * @return new cloned configuration object
+   */
+  public Configuration clone(String username, String password) {
+    return new Configuration(
+        username != null && username.isEmpty() ? null : username,
+        password != null && password.isEmpty() ? null : password,
+        this.database,
+        this.addresses,
+        this.haMode,
+        this.nonMappedOptions,
+        this.timezone,
+        this.autocommit,
+        this.useMysqlMetadata,
+        this.createDatabaseIfNotExist,
+        this.transactionIsolation,
+        this.defaultFetchSize,
+        this.maxQuerySizeToLog,
+        this.maxAllowedPacket,
+        this.geometryDefaultType,
+        this.restrictedAuth,
+        this.initSql,
+        this.socketFactory,
+        this.connectTimeout,
+        this.pipe,
+        this.localSocket,
+        this.tcpKeepAlive,
+        this.uuidAsString,
+        this.tcpKeepIdle,
+        this.tcpKeepCount,
+        this.tcpKeepInterval,
+        this.tcpAbortiveClose,
+        this.localSocketAddress,
+        this.socketTimeout,
+        this.useReadAheadInput,
+        this.tlsSocketType,
+        this.sslMode,
+        this.serverSslCert,
+        this.keyStore,
+        this.keyStorePassword,
+        this.keyStoreType,
+        this.enabledSslCipherSuites,
+        this.enabledSslProtocolSuites,
+        this.allowMultiQueries,
+        this.allowLocalInfile,
+        this.useCompression,
+        this.useAffectedRows,
+        this.useBulkStmts,
+        this.disablePipeline,
+        this.cachePrepStmts,
+        this.prepStmtCacheSize,
+        this.useServerPrepStmts,
+        this.credentialType,
+        this.sessionVariables,
+        this.connectionAttributes,
+        this.servicePrincipalName,
+        this.blankTableNameMeta,
+        this.tinyInt1isBit,
+        this.transformedBitIsBoolean,
+        this.yearIsDateType,
+        this.dumpQueriesOnException,
+        this.includeInnodbStatusInDeadlockExceptions,
+        this.includeThreadDumpInDeadlockExceptions,
+        this.retriesAllDown,
+        this.galeraAllowedState,
+        this.transactionReplay,
+        this.transactionReplaySize,
+        this.pool,
+        this.poolName,
+        this.maxPoolSize,
+        this.minPoolSize,
+        this.maxIdleTime,
+        this.registerJmxPool,
+        this.poolValidMinDelay,
+        this.useResetConnection,
+        this.serverRsaPublicKeyFile,
+        this.allowPublicKeyRetrieval);
+  }
+
+  /**
+   * Connection default database
+   *
+   * @return database
+   */
+  public String database() {
+    return database;
+  }
+
+  /**
+   * addresses
+   *
+   * @return addresses
+   */
+  public List<HostAddress> addresses() {
+    return addresses;
+  }
+
+  /**
+   * High availability mode
+   *
+   * @return configuration HA mode
+   */
+  public HaMode haMode() {
+    return haMode;
+  }
+
+  /**
+   * credential plugin to use
+   *
+   * @return credential plugin to use, null of none
+   */
+  public CredentialPlugin credentialPlugin() {
+    return credentialType;
+  }
+
+  /**
+   * configuration user
+   *
+   * @return user
+   */
+  public String user() {
+    return user;
+  }
+
+  /**
+   * configuration password
+   *
+   * @return password
+   */
+  public String password() {
+    return password;
+  }
+
+  /**
+   * Configuration generated URL depending on current configuration option. Password will be hidden
+   * by "***"
+   *
+   * @return generated url
+   */
+  public String initialUrl() {
+    return initialUrl;
+  }
+
+  /**
+   * server ssl certificate (file path / certificat content)
+   *
+   * @return server ssl certificate
+   */
+  public String serverSslCert() {
+    return serverSslCert;
+  }
+
+  /**
+   * key store
+   *
+   * @return key store
+   */
+  public String keyStore() {
+    return keyStore;
+  }
+
+  /**
+   * key store password
+   *
+   * @return key store password
+   */
+  public String keyStorePassword() {
+    return keyStorePassword;
+  }
+
+  /**
+   * key store type (to replace default javax.net.ssl.keyStoreType system property)
+   *
+   * @return key store type
+   */
+  public String keyStoreType() {
+    return keyStoreType;
+  }
+
+  /**
+   * permitted ssl protocol list (comma separated)
+   *
+   * @return enabled ssl protocol list
+   */
+  public String enabledSslProtocolSuites() {
+    return enabledSslProtocolSuites;
+  }
+
+  /**
+   * Socket factory class name
+   *
+   * @return socket factory
+   */
+  public String socketFactory() {
+    return socketFactory;
+  }
+
+  /**
+   * socket connect timeout
+   *
+   * @return connect timeout
+   */
+  public int connectTimeout() {
+    return connectTimeout;
+  }
+
+  /**
+   * Set connect timeout
+   *
+   * @param connectTimeout timeout value
+   * @return current configuration
+   */
+  public Configuration connectTimeout(int connectTimeout) {
+    this.connectTimeout = connectTimeout;
+    return this;
+  }
+
+  /**
+   * Pipe path
+   *
+   * @return pipe value
+   */
+  public String pipe() {
+    return pipe;
+  }
+
+  /**
+   * local socket configuration
+   *
+   * @return local socket path
+   */
+  public String localSocket() {
+    return localSocket;
+  }
+
+  /**
+   * socket tcp keep alive
+   *
+   * @return socket tcp keep alive value
+   */
+  public boolean tcpKeepAlive() {
+    return tcpKeepAlive;
+  }
+
+  /**
+   * must uuid fields return as String and not java.util.UUID
+   *
+   * @return must UUID return as String and not uuid
+   */
+  public boolean uuidAsString() {
+    return uuidAsString;
+  }
+
+  /**
+   * socket tcp keep idle (java 11+ only)
+   *
+   * @return socket tcp keep idle
+   */
+  public int tcpKeepIdle() {
+    return tcpKeepIdle;
+  }
+
+  /**
+   * socket tcp keep count (java 11+ only)
+   *
+   * @return socket tcp keep count
+   */
+  public int tcpKeepCount() {
+    return tcpKeepCount;
+  }
+
+  /**
+   * socket tcp keep interval (java 11+ only)
+   *
+   * @return socket tcp keep interval
+   */
+  public int tcpKeepInterval() {
+    return tcpKeepInterval;
+  }
+
+  /**
+   * close using TCP abortive close (RST TCP packet, in place or FIN packet)
+   *
+   * @return close using TCP abortive close
+   */
+  public boolean tcpAbortiveClose() {
+    return tcpAbortiveClose;
+  }
+
+  /**
+   * local socket address path
+   *
+   * @return local socket address
+   */
+  public String localSocketAddress() {
+    return localSocketAddress;
+  }
+
+  /**
+   * socket timeout
+   *
+   * @return socket timeout
+   */
+  public int socketTimeout() {
+    return socketTimeout;
+  }
+
+  /**
+   * permit using multi queries command
+   *
+   * @return permit using multi queries command
+   */
+  public boolean allowMultiQueries() {
+    return allowMultiQueries;
+  }
+
+  /**
+   * permits LOAD LOCAL INFILE commands
+   *
+   * @return allow LOAD LOCAL INFILE
+   */
+  public boolean allowLocalInfile() {
+    return allowLocalInfile;
+  }
+
+  /**
+   * Enable compression if server has compression capability
+   *
+   * @return use compression
+   */
+  public boolean useCompression() {
+    return useCompression;
+  }
+
+  /**
+   * force returning blank table metadata (for old oracle compatibility)
+   *
+   * @return metadata table return blank
+   */
+  public boolean blankTableNameMeta() {
+    return blankTableNameMeta;
+  }
+
+  /**
+   * SSl mode
+   *
+   * @return ssl mode
+   */
+  public SslMode sslMode() {
+    return sslMode;
+  }
+
+  /**
+   * Default transaction isolation
+   *
+   * @return default transaction isolation.
+   */
+  public TransactionIsolation transactionIsolation() {
+    return transactionIsolation;
+  }
+
+  /**
+   * autorized cipher list.
+   *
+   * @return list of permitted ciphers
+   */
+  public String enabledSslCipherSuites() {
+    return enabledSslCipherSuites;
+  }
+
+  /**
+   * coma separated Session variable list
+   *
+   * @return session variable
+   */
+  public String sessionVariables() {
+    return sessionVariables;
+  }
+
+  /**
+   * Must tinyint(1) be considered as Bit
+   *
+   * @return true if tinyint(1) must be considered as Bit
+   */
+  public boolean tinyInt1isBit() {
+    return tinyInt1isBit;
+  }
+
+  /**
+   * Must tinyint(1) be considered as Boolean or Bit
+   *
+   * @return true if tinyint(1) must be considered as Boolean
+   */
+  public boolean transformedBitIsBoolean() {
+    return transformedBitIsBoolean;
+  }
+
+  /**
+   * Must year be return by default as Date in result-set
+   *
+   * @return year is Date type
+   */
+  public boolean yearIsDateType() {
+    return yearIsDateType;
+  }
+
+  /**
+   * Set timezone
+   *
+   * @return timezone
+   */
+  public String timezone() {
+    return timezone;
+  }
+
+  /**
+   * Must query by logged on exception.
+   *
+   * @return dump queries on exception
+   */
+  public boolean dumpQueriesOnException() {
+    return dumpQueriesOnException;
+  }
+
+  /**
+   * Prepare statement cache size.
+   *
+   * @return Prepare statement cache size
+   */
+  public int prepStmtCacheSize() {
+    return prepStmtCacheSize;
+  }
+
+  /**
+   * Use affected row
+   *
+   * @return use affected rows
+   */
+  public boolean useAffectedRows() {
+    return useAffectedRows;
+  }
+
+  /**
+   * Use server prepared statement. IF false, using client prepared statement.
+   *
+   * @return use server prepared statement
+   */
+  public boolean useServerPrepStmts() {
+    return useServerPrepStmts;
+  }
+
+  /**
+   * Connections attributes
+   *
+   * @return connection meta informations
+   */
+  public String connectionAttributes() {
+    return connectionAttributes;
+  }
+
+  /**
+   * Use server COM_STMT_BULK for batching.
+   *
+   * @return use server bulk command.
+   */
+  public boolean useBulkStmts() {
+    return useBulkStmts;
+  }
+
+  /**
+   * Disable pipeline.
+   *
+   * @return is pipeline disabled.
+   */
+  public boolean disablePipeline() {
+    return disablePipeline;
+  }
+
+  /**
+   * Force session autocommit on connection creation
+   *
+   * @return autocommit forced value
+   */
+  public Boolean autocommit() {
+    return autocommit;
+  }
+
+  /**
+   * Force returning MySQL metadata information
+   *
+   * @return force returning MySQL in metadata
+   */
+  public boolean useMysqlMetadata() {
+    return useMysqlMetadata;
+  }
+
+  /**
+   * create database if not exist
+   *
+   * @return create database if not exist
+   */
+  public boolean createDatabaseIfNotExist() {
+    return createDatabaseIfNotExist;
+  }
+
+  /**
+   * On deadlock exception, must driver execute additional commands to show innodb status in error
+   * description.
+   *
+   * @return includeInnodbStatusInDeadlockExceptions
+   */
+  public boolean includeInnodbStatusInDeadlockExceptions() {
+    return includeInnodbStatusInDeadlockExceptions;
+  }
+
+  /**
+   * On deadlock exception, must driver display threads information on error description.
+   *
+   * @return include Thread Dump In Deadlock Exceptions
+   */
+  public boolean includeThreadDumpInDeadlockExceptions() {
+    return includeThreadDumpInDeadlockExceptions;
+  }
+
+  /**
+   * Service principal name (GSSAPI option)
+   *
+   * @return service principal name
+   */
+  public String servicePrincipalName() {
+    return servicePrincipalName;
+  }
+
+  /**
+   * result-set streaming default fetch size
+   *
+   * @return Default fetch size.
+   */
+  public int defaultFetchSize() {
+    return defaultFetchSize;
+  }
+
+  /**
+   * non standard options
+   *
+   * @return non standard options
+   */
+  public Properties nonMappedOptions() {
+    return nonMappedOptions;
+  }
+
+  /**
+   * TLS socket type
+   *
+   * @return TLS socket type
+   */
+  public String tlsSocketType() {
+    return tlsSocketType;
+  }
+
+  /**
+   * query maximum size to log (query will be truncated of more than this limit)
+   *
+   * @return max query log size
+   */
+  public int maxQuerySizeToLog() {
+    return maxQuerySizeToLog;
+  }
+
+  /**
+   * max_allowed_packet value to avoid sending packet with non supported size, droping the
+   * connection without reason.
+   *
+   * @return max_allowed_packet value
+   */
+  public Integer maxAllowedPacket() {
+    return maxAllowedPacket;
+  }
+
+  /**
+   * retry the maximum retry number of attempts to reconnect after a failover.
+   *
+   * @return the maximum retry number of attempts to reconnect after a failover.
+   */
+  public int retriesAllDown() {
+    return retriesAllDown;
+  }
+
+  /**
+   * Galera comma separated allowed state
+   *
+   * @return galera allowed state
+   */
+  public String galeraAllowedState() {
+    return galeraAllowedState;
+  }
+
+  /**
+   * Create pool
+   *
+   * @return create pool if don't exists
+   */
+  public boolean pool() {
+    return pool;
+  }
+
+  /**
+   * pool name
+   *
+   * @return pool name.
+   */
+  public String poolName() {
+    return poolName;
+  }
+
+  /**
+   * max pool size
+   *
+   * @return maximum pool size
+   */
+  public int maxPoolSize() {
+    return maxPoolSize;
+  }
+
+  /**
+   * Minimum pool size
+   *
+   * @return minimum pool size
+   */
+  public int minPoolSize() {
+    return minPoolSize;
+  }
+
+  /**
+   * Max idle time
+   *
+   * @return pool max idle time.
+   */
+  public int maxIdleTime() {
+    return maxIdleTime;
+  }
+
+  /**
+   * register pool information to JMX
+   *
+   * @return register pool to JMX
+   */
+  public boolean registerJmxPool() {
+    return registerJmxPool;
+  }
+
+  /**
+   * Pool mininum validation delay.
+   *
+   * @return pool validation delay
+   */
+  public int poolValidMinDelay() {
+    return poolValidMinDelay;
+  }
+
+  /**
+   * Must connection returned to pool be RESET
+   *
+   * @return use RESET on connection
+   */
+  public boolean useResetConnection() {
+    return useResetConnection;
+  }
+
+  /**
+   * Server RSA public key file for caching_sha2_password authentication
+   *
+   * @return server key file
+   */
+  public String serverRsaPublicKeyFile() {
+    return serverRsaPublicKeyFile;
+  }
+
+  /**
+   * permit mysql authentication to retrieve server certificate
+   *
+   * @return is driver allowed to retrieve server certificate from server
+   */
+  public boolean allowPublicKeyRetrieval() {
+    return allowPublicKeyRetrieval;
+  }
+
+  /**
+   * Read all data from socket in advance
+   *
+   * @return use read ahead buffer implementation
+   */
+  public boolean useReadAheadInput() {
+    return useReadAheadInput;
+  }
+
+  /**
+   * Cache prepared statement result.
+   *
+   * @return cache prepare results
+   */
+  public boolean cachePrepStmts() {
+    return cachePrepStmts;
+  }
+
+  /**
+   * implements transaction replay failover
+   *
+   * @return true if transaction must be replayed on failover.
+   */
+  public boolean transactionReplay() {
+    return transactionReplay;
+  }
+
+  /**
+   * transaction replay maximum number of saved command.
+   *
+   * @return transaction replay buffer size.
+   */
+  public int transactionReplaySize() {
+    return transactionReplaySize;
+  }
+
+  /**
+   * geometry default decoding implementation
+   *
+   * @return geometry default type
+   */
+  public String geometryDefaultType() {
+    return geometryDefaultType;
+  }
+
+  /**
+   * Restrict authentication plugin to comma separated plugin list
+   *
+   * @return authorized authentication list
+   */
+  public String restrictedAuth() {
+    return restrictedAuth;
+  }
+
+  /**
+   * Execute initial command when connection is established
+   *
+   * @return initial SQL command
+   */
+  public String initSql() {
+    return initSql;
+  }
+
+  /**
+   * datatype Encoder/decoder list
+   *
+   * @return codec list
+   */
+  public Codec<?>[] codecs() {
+    return codecs;
+  }
+
+  /**
+   * ToString implementation.
+   *
+   * @return String value
+   */
+  public String toString() {
+    return initialUrl;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    Configuration that = (Configuration) o;
+
+    if (password == null) {
+      return initialUrl.equals(that.initialUrl) && that.password == null;
+    }
+    return initialUrl.equals(that.initialUrl) && password.equals(that.password);
+  }
+
+  /**
+   * Generate initialURL property
+   *
+   * @param conf current configuration
+   * @return initialUrl value.
+   */
+  protected static String buildUrl(Configuration conf) {
+    Configuration defaultConf = new Configuration();
+    StringBuilder sb = new StringBuilder();
+    sb.append("jdbc:mariadb:");
+    if (conf.haMode != HaMode.NONE) {
+      sb.append(conf.haMode.toString().toLowerCase(Locale.ROOT)).append(":");
+    }
+    sb.append("//");
+    for (int i = 0; i < conf.addresses.size(); i++) {
+      HostAddress hostAddress = conf.addresses.get(i);
+      if (i > 0) {
+        sb.append(",");
+      }
+      if ((conf.haMode == HaMode.NONE && hostAddress.primary)
+          || (conf.haMode == HaMode.REPLICATION
+              && ((i == 0 && hostAddress.primary) || (i != 0 && !hostAddress.primary)))) {
+        sb.append(hostAddress.host);
+        if (hostAddress.port != 3306) sb.append(":").append(hostAddress.port);
+      } else {
+        sb.append("address=(host=")
+            .append(hostAddress.host)
+            .append(")")
+            .append("(port=")
+            .append(hostAddress.port)
+            .append(")");
+        sb.append("(type=").append(hostAddress.primary ? "primary" : "replica").append(")");
+      }
+    }
+
+    sb.append("/");
+    if (conf.database != null) {
+      sb.append(conf.database);
+    }
+
+    try {
+      // Option object is already initialized to default values.
+      // loop on properties,
+      // - check DefaultOption to check that property value correspond to type (and range)
+      // - set values
+      boolean first = true;
+
+      Field[] fields = Configuration.class.getDeclaredFields();
+      for (Field field : fields) {
+        if ("database".equals(field.getName())
+            || "haMode".equals(field.getName())
+            || "$jacocoData".equals(field.getName())
+            || "addresses".equals(field.getName())) {
+          continue;
+        }
+        Object obj = field.get(conf);
+
+        if (obj != null && (!(obj instanceof Properties) || ((Properties) obj).size() > 0)) {
+
+          if ("password".equals(field.getName())) {
+            sb.append(first ? '?' : '&');
+            first = false;
+            sb.append(field.getName()).append('=');
+            sb.append("***");
+            continue;
+          }
+
+          if (field.getType().equals(String.class)) {
+            sb.append(first ? '?' : '&');
+            first = false;
+            sb.append(field.getName()).append('=');
+            sb.append((String) obj);
+          } else if (field.getType().equals(boolean.class)) {
+            boolean defaultValue = field.getBoolean(defaultConf);
+            if (!obj.equals(defaultValue)) {
+              sb.append(first ? '?' : '&');
+              first = false;
+              sb.append(field.getName()).append('=');
+              sb.append(obj);
+            }
+          } else if (field.getType().equals(int.class)) {
+            try {
+              int defaultValue = field.getInt(defaultConf);
+              if (!obj.equals(defaultValue)) {
+                sb.append(first ? '?' : '&');
+                sb.append(field.getName()).append('=').append(obj);
+                first = false;
+              }
+            } catch (IllegalAccessException n) {
+              // eat
+            }
+          } else if (field.getType().equals(Properties.class)) {
+            sb.append(first ? '?' : '&');
+            first = false;
+            boolean firstProp = true;
+            Properties properties = (Properties) obj;
+            for (Object key : properties.keySet()) {
+              if (firstProp) {
+                firstProp = false;
+              } else {
+                sb.append('&');
+              }
+              sb.append(key).append('=');
+              sb.append(properties.get(key));
+            }
+          } else if (field.getType().equals(CredentialPlugin.class)) {
+            Object defaultValue = field.get(defaultConf);
+            if (!obj.equals(defaultValue)) {
+              sb.append(first ? '?' : '&');
+              first = false;
+              sb.append(field.getName()).append('=');
+              sb.append(((CredentialPlugin) obj).type());
+            }
+          } else {
+            Object defaultValue = field.get(defaultConf);
+            if (!obj.equals(defaultValue)) {
+              sb.append(first ? '?' : '&');
+              first = false;
+              sb.append(field.getName()).append('=');
+              sb.append(obj);
+            }
+          }
+        }
+      }
+
+    } catch (IllegalAccessException n) {
+      n.printStackTrace();
+    } catch (SecurityException s) {
+      // only for jws, so never thrown
+      throw new IllegalArgumentException("Security too restrictive : " + s.getMessage());
+    }
+    conf.loadCodecs();
+    return sb.toString();
+  }
+
+  @SuppressWarnings("rawtypes")
+  private void loadCodecs() {
+    ServiceLoader<Codec> loader =
+        ServiceLoader.load(Codec.class, Configuration.class.getClassLoader());
+    List<Codec<?>> result = new ArrayList<>();
+    loader.iterator().forEachRemaining(result::add);
+    codecs = result.toArray(new Codec<?>[0]);
+  }
+
+  @Override
+  public int hashCode() {
+    return initialUrl.hashCode();
+  }
+
+  /** A builder for {@link Configuration} instances. */
+  public static final class Builder implements Cloneable {
+
+    private Properties _nonMappedOptions;
+    private HaMode _haMode;
+    private List<HostAddress> _addresses = new ArrayList<>();
+
+    // standard options
+    private String user;
+    private String password;
+    private String database;
+
+    // various
+    private String timezone;
+    private Boolean autocommit;
+    private Boolean useMysqlMetadata;
+    private Boolean createDatabaseIfNotExist;
+    private Integer defaultFetchSize;
+    private Integer maxQuerySizeToLog;
+    private Integer maxAllowedPacket;
+    private String geometryDefaultType;
+    private String restrictedAuth;
+    private String initSql;
+    private String transactionIsolation;
+
+    // socket
+    private String socketFactory;
+    private Integer connectTimeout;
+    private String pipe;
+    private String localSocket;
+    private Boolean tcpKeepAlive;
+    private Boolean uuidAsString;
+    private Integer tcpKeepIdle;
+    private Integer tcpKeepCount;
+    private Integer tcpKeepInterval;
+    private Boolean tcpAbortiveClose;
+    private String localSocketAddress;
+    private Integer socketTimeout;
+    private Boolean useReadAheadInput;
+    private String tlsSocketType;
+
+    // SSL
+    private String sslMode;
+    private String serverSslCert;
+    private String keyStore;
+    private String keyStorePassword;
+    private String keyStoreType;
+    private String enabledSslCipherSuites;
+    private String enabledSslProtocolSuites;
+
+    // protocol
+    private Boolean allowMultiQueries;
+    private Boolean allowLocalInfile;
+    private Boolean useCompression;
+    private Boolean useAffectedRows;
+    private Boolean useBulkStmts;
+    private Boolean disablePipeline;
+    // prepare
+    private Boolean cachePrepStmts;
+    private Integer prepStmtCacheSize;
+    private Boolean useServerPrepStmts;
+
+    // authentication
+    private String credentialType;
+    private String sessionVariables;
+    private String connectionAttributes;
+    private String servicePrincipalName;
+
+    // meta
+    private Boolean blankTableNameMeta;
+    private Boolean tinyInt1isBit;
+
+    private Boolean transformedBitIsBoolean;
+    private Boolean yearIsDateType;
+    private Boolean dumpQueriesOnException;
+    private Boolean includeInnodbStatusInDeadlockExceptions;
+    private Boolean includeThreadDumpInDeadlockExceptions;
+
+    // HA options
+    private Integer retriesAllDown;
+    private String galeraAllowedState;
+    private Boolean transactionReplay;
+    private Integer transactionReplaySize;
+
+    // Pool options
+    private Boolean pool;
+    private String poolName;
+    private Integer maxPoolSize;
+    private Integer minPoolSize;
+    private Integer maxIdleTime;
+    private Boolean registerJmxPool;
+    private Integer poolValidMinDelay;
+    private Boolean useResetConnection;
+
+    // MySQL sha authentication
+    private String serverRsaPublicKeyFile;
+    private Boolean allowPublicKeyRetrieval;
+
+    /**
+     * set user to authenticate to server
+     *
+     * @param user user
+     * @return this {@link Builder}
+     */
+    public Builder user(String user) {
+      this.user = nullOrEmpty(user);
+      return this;
+    }
+
+    /**
+     * Server SSL certificate (path or file content)
+     *
+     * @param serverSslCert set Server SSL certificate (path or file content)
+     * @return this {@link Builder}
+     */
+    public Builder serverSslCert(String serverSslCert) {
+      this.serverSslCert = nullOrEmpty(serverSslCert);
+      return this;
+    }
+
+    /**
+     * File path of the keyStore file that contain client private key store and associate
+     * certificates (similar to java System property \"javax.net.ssl.keyStore\", but ensure that
+     * only the private key's entries are used)
+     *
+     * @param keyStore client store certificates
+     * @return this {@link Builder}
+     */
+    public Builder keyStore(String keyStore) {
+      this.keyStore = nullOrEmpty(keyStore);
+      return this;
+    }
+
+    /**
+     * Client keystore password
+     *
+     * @param keyStorePassword client store password
+     * @return this {@link Builder}
+     */
+    public Builder keyStorePassword(String keyStorePassword) {
+      this.keyStorePassword = nullOrEmpty(keyStorePassword);
+      return this;
+    }
+
+    /**
+     * Key store type
+     *
+     * @param keyStoreType key store type
+     * @return this {@link Builder}
+     */
+    public Builder keyStoreType(String keyStoreType) {
+      this.keyStoreType = nullOrEmpty(keyStoreType);
+      return this;
+    }
+
+    /**
+     * User password
+     *
+     * @param password password
+     * @return this {@link Builder}
+     */
+    public Builder password(String password) {
+      this.password = nullOrEmpty(password);
+      return this;
+    }
+
+    /**
+     * Set ssl protocol list to user (comma separated)
+     *
+     * @param enabledSslProtocolSuites set possible SSL(TLS) protocol to use
+     * @return this {@link Builder}
+     */
+    public Builder enabledSslProtocolSuites(String enabledSslProtocolSuites) {
+      this.enabledSslProtocolSuites = nullOrEmpty(enabledSslProtocolSuites);
+      return this;
+    }
+
+    /**
+     * Set default database
+     *
+     * @param database database
+     * @return this {@link Builder}
+     */
+    public Builder database(String database) {
+      this.database = database;
+      return this;
+    }
+
+    /**
+     * Set failover High-availability mode
+     *
+     * @param haMode High-availability mode
+     * @return this {@link Builder}
+     */
+    public Builder haMode(HaMode haMode) {
+      this._haMode = haMode;
+      return this;
+    }
+
+    /**
+     * Add Host to possible addresses to connect
+     *
+     * @param host hostname or IP
+     * @param port port
+     * @return this {@link Builder}
+     */
+    public Builder addHost(String host, int port) {
+      this._addresses.add(HostAddress.from(nullOrEmpty(host), port));
+      return this;
+    }
+
+    /**
+     * Add Host to possible addresses to connect
+     *
+     * @param host hostname or IP
+     * @param port port
+     * @param master is master or replica
+     * @return this {@link Builder}
+     */
+    public Builder addHost(String host, int port, boolean master) {
+      this._addresses.add(HostAddress.from(nullOrEmpty(host), port, master));
+      return this;
+    }
+
+    /**
+     * add host addresses
+     *
+     * @param hostAddress host addresses
+     * @return this {@link Builder}
+     */
+    public Builder addresses(HostAddress... hostAddress) {
+      this._addresses = new ArrayList<>();
+      this._addresses.addAll(Arrays.asList(hostAddress));
+      return this;
+    }
+
+    /**
+     * Socket factory
+     *
+     * @param socketFactory socket factory
+     * @return this {@link Builder}
+     */
+    public Builder socketFactory(String socketFactory) {
+      this.socketFactory = socketFactory;
+      return this;
+    }
+
+    /**
+     * Indicate connect timeout value, in milliseconds, or zero for no timeout. Default: 30000
+     *
+     * @param connectTimeout connect Timeout
+     * @return this {@link Builder}
+     */
+    public Builder connectTimeout(Integer connectTimeout) {
+      this.connectTimeout = connectTimeout;
+      return this;
+    }
+
+    /**
+     * Indicate to use windows named pipe, specify named pipe name to connect
+     *
+     * @param pipe windows named pipe
+     * @return this {@link Builder}
+     */
+    public Builder pipe(String pipe) {
+      this.pipe = nullOrEmpty(pipe);
+      return this;
+    }
+
+    /**
+     * Indicate to use Unix domain socket, if the server allows it, specifying named pipe name to
+     * connect The value is the path of Unix domain socket (available with "select @@socket"
+     * command).
+     *
+     * @param localSocket local socket path
+     * @return this {@link Builder}
+     */
+    public Builder localSocket(String localSocket) {
+      this.localSocket = nullOrEmpty(localSocket);
+      return this;
+    }
+
+    /**
+     * Indicate if TCP keep-alive must be enabled.
+     *
+     * @param tcpKeepAlive value
+     * @return this {@link Builder}
+     */
+    public Builder tcpKeepAlive(Boolean tcpKeepAlive) {
+      this.tcpKeepAlive = tcpKeepAlive;
+      return this;
+    }
+
+    /**
+     * Indicate if UUID fields must returns as String
+     *
+     * @param uuidAsString value
+     * @return this {@link Builder}
+     */
+    public Builder uuidAsString(Boolean uuidAsString) {
+      this.uuidAsString = uuidAsString;
+      return this;
+    }
+
+    /**
+     * Indicate TCP keep-idle value (for java 11+ only).
+     *
+     * @param tcpKeepIdle value
+     * @return this {@link Builder}
+     */
+    public Builder tcpKeepIdle(Integer tcpKeepIdle) {
+      this.tcpKeepIdle = tcpKeepIdle;
+      return this;
+    }
+
+    /**
+     * Indicate TCP keep-count value (for java 11+ only).
+     *
+     * @param tcpKeepCount value
+     * @return this {@link Builder}
+     */
+    public Builder tcpKeepCount(Integer tcpKeepCount) {
+      this.tcpKeepCount = tcpKeepCount;
+      return this;
+    }
+
+    /**
+     * Indicate TCP keep-interval value (for java 11+ only).
+     *
+     * @param tcpKeepInterval value
+     * @return this {@link Builder}
+     */
+    public Builder tcpKeepInterval(Integer tcpKeepInterval) {
+      this.tcpKeepInterval = tcpKeepInterval;
+      return this;
+    }
+
+    /**
+     * Indicate that when connection fails, to send an RST TCP packet.
+     *
+     * @param tcpAbortiveClose value
+     * @return this {@link Builder}
+     */
+    public Builder tcpAbortiveClose(Boolean tcpAbortiveClose) {
+      this.tcpAbortiveClose = tcpAbortiveClose;
+      return this;
+    }
+
+    /**
+     * Indicate what default Object type Geometry a resultset.getObject must return. possibility :
+     *
+     * <ul>
+     *   <li>null or empty is WKB byte array
+     *   <li>'default' will return org.mariadb.mariadb.jdbc.type Object
+     * </ul>
+     *
+     * In the future JTS might be implemented
+     *
+     * @param geometryDefault value
+     * @return this {@link Builder}
+     */
+    public Builder geometryDefaultType(String geometryDefault) {
+      this.geometryDefaultType = nullOrEmpty(geometryDefault);
+      return this;
+    }
+
+    /**
+     * restrict authentication method to secure list. Default "default".
+     *
+     * @param restrictedAuth use authentication plugin list
+     * @return this {@link Builder}
+     */
+    public Builder restrictedAuth(String restrictedAuth) {
+      this.restrictedAuth = restrictedAuth;
+      return this;
+    }
+
+    /**
+     * permit to execute an SQL command on connection creation
+     *
+     * @param initSql initial SQL command
+     * @return this {@link Builder}
+     */
+    public Builder initSql(String initSql) {
+      this.initSql = initSql;
+      return this;
+    }
+
+    /**
+     * Indicate Hostname or IP address to bind the connection socket to a local (UNIX domain)
+     * socket.
+     *
+     * @param localSocketAddress Hostname or IP address
+     * @return this {@link Builder}
+     */
+    public Builder localSocketAddress(String localSocketAddress) {
+      this.localSocketAddress = nullOrEmpty(localSocketAddress);
+      return this;
+    }
+
+    /**
+     * Indicate the network socket timeout (SO_TIMEOUT) in milliseconds. Value of 0 disables this
+     * timeout.
+     *
+     * <p>If the goal is to set a timeout for all queries, the server has permitted a solution to
+     * limit the query time by setting a system variable, max_statement_time. Default: 0
+     *
+     * @param socketTimeout socket timeout value
+     * @return this {@link Builder}
+     */
+    public Builder socketTimeout(Integer socketTimeout) {
+      this.socketTimeout = socketTimeout;
+      return this;
+    }
+
+    /**
+     * Indicate that multi-queries are allowed. example: "insert into ab (i) values (1); insert into
+     * ab (i) values (2)".
+     *
+     * <p>If application build sql command string, this is probably a bad idea to enable this
+     * option, opening the door to sql injection. default: false.
+     *
+     * @param allowMultiQueries indicate if active
+     * @return this {@link Builder}
+     */
+    public Builder allowMultiQueries(Boolean allowMultiQueries) {
+      this.allowMultiQueries = allowMultiQueries;
+      return this;
+    }
+
+    /**
+     * Indicate if LOAD DATA LOCAL INFILE are permitted. This will disable all pipelining
+     * implementation.
+     *
+     * @param allowLocalInfile indicate if permit LOAD DATA LOCAL INFILE commands
+     * @return this {@link Builder}
+     */
+    public Builder allowLocalInfile(Boolean allowLocalInfile) {
+      this.allowLocalInfile = allowLocalInfile;
+      return this;
+    }
+
+    /**
+     * Indicate to compress exchanges with the database through gzip. This permits better
+     * performance when the database is not in the same location.
+     *
+     * @param useCompression to enable/disable compression
+     * @return this {@link Builder}
+     */
+    public Builder useCompression(Boolean useCompression) {
+      this.useCompression = useCompression;
+      return this;
+    }
+
+    /**
+     * Set blank table name for metadata (old oracle compatibility)
+     *
+     * @param blankTableNameMeta use blank table name
+     * @return this {@link Builder}
+     */
+    public Builder blankTableNameMeta(Boolean blankTableNameMeta) {
+      this.blankTableNameMeta = blankTableNameMeta;
+      return this;
+    }
+
+    /**
+     * set credential plugin type
+     *
+     * @param credentialType credential plugin type
+     * @return this {@link Builder}
+     */
+    public Builder credentialType(String credentialType) {
+      this.credentialType = nullOrEmpty(credentialType);
+      return this;
+    }
+
+    /**
+     * Set ssl model
+     *
+     * @param sslMode ssl requirement
+     * @return this {@link Builder}
+     */
+    public Builder sslMode(String sslMode) {
+      this.sslMode = sslMode;
+      return this;
+    }
+
+    /**
+     * force default transaction isolation, not using server default
+     *
+     * @param transactionIsolation indicate default transaction isolation
+     * @return this {@link Builder}
+     */
+    public Builder transactionIsolation(String transactionIsolation) {
+      this.transactionIsolation = nullOrEmpty(transactionIsolation);
+      return this;
+    }
+
+    /**
+     * set possible cipher list (comma separated), not using default java cipher list
+     *
+     * @param enabledSslCipherSuites ssl cipher list
+     * @return this {@link Builder}
+     */
+    public Builder enabledSslCipherSuites(String enabledSslCipherSuites) {
+      this.enabledSslCipherSuites = nullOrEmpty(enabledSslCipherSuites);
+      return this;
+    }
+
+    /**
+     * set connection session variables (comma separated)
+     *
+     * @param sessionVariables session variable list
+     * @return this {@link Builder}
+     */
+    public Builder sessionVariables(String sessionVariables) {
+      this.sessionVariables = nullOrEmpty(sessionVariables);
+      return this;
+    }
+
+    /**
+     * TinyInt(1) to be considered as bit
+     *
+     * @param tinyInt1isBit Indicate if Tinyint(1) to be considered as bit
+     * @return this {@link Builder}
+     */
+    public Builder tinyInt1isBit(Boolean tinyInt1isBit) {
+      this.tinyInt1isBit = tinyInt1isBit;
+      return this;
+    }
+
+    /**
+     * TinyInt(1) to be considered as boolean
+     *
+     * @param transformedBitIsBoolean Indicate if Tinyint(1) to be considered as boolean
+     * @return this {@link Builder}
+     */
+    public Builder transformedBitIsBoolean(Boolean transformedBitIsBoolean) {
+      this.transformedBitIsBoolean = transformedBitIsBoolean;
+      return this;
+    }
+
+    /**
+     * Year datatype to be considered as date
+     *
+     * @param yearIsDateType indicate if Year must be considered as Date
+     * @return this {@link Builder}
+     */
+    public Builder yearIsDateType(Boolean yearIsDateType) {
+      this.yearIsDateType = yearIsDateType;
+      return this;
+    }
+
+    /**
+     * Force timezone to use this timezone, not default java one
+     *
+     * @param timezone default timezone
+     * @return this {@link Builder}
+     */
+    public Builder timezone(String timezone) {
+      this.timezone = nullOrEmpty(timezone);
+      return this;
+    }
+
+    /**
+     * Must queries be dump on exception stracktrace.
+     *
+     * @param dumpQueriesOnException must queries be dump on exception
+     * @return this {@link Builder}
+     */
+    public Builder dumpQueriesOnException(Boolean dumpQueriesOnException) {
+      this.dumpQueriesOnException = dumpQueriesOnException;
+      return this;
+    }
+
+    /**
+     * If using server prepared statement, set LRU prepare cache size
+     *
+     * @param prepStmtCacheSize prepare cache size
+     * @return this {@link Builder}
+     */
+    public Builder prepStmtCacheSize(Integer prepStmtCacheSize) {
+      this.prepStmtCacheSize = prepStmtCacheSize;
+      return this;
+    }
+
+    /**
+     * Indicate server to return affected rows in place of found rows. This impact the return number
+     * of rows affected by update
+     *
+     * @param useAffectedRows Indicate to user affected rows in place of found rows
+     * @return this {@link Builder}
+     */
+    public Builder useAffectedRows(Boolean useAffectedRows) {
+      this.useAffectedRows = useAffectedRows;
+      return this;
+    }
+
+    /**
+     * Indicate to use Client or Server prepared statement
+     *
+     * @param useServerPrepStmts use Server prepared statement
+     * @return this {@link Builder}
+     */
+    public Builder useServerPrepStmts(Boolean useServerPrepStmts) {
+      this.useServerPrepStmts = useServerPrepStmts;
+      return this;
+    }
+
+    /**
+     * Additional connection attributes to identify connection
+     *
+     * @param connectionAttributes additional connection attributes
+     * @return this {@link Builder}
+     */
+    public Builder connectionAttributes(String connectionAttributes) {
+      this.connectionAttributes = nullOrEmpty(connectionAttributes);
+      return this;
+    }
+
+    /**
+     * Use server dedicated bulk batch command
+     *
+     * @param useBulkStmts use server bulk batch command.
+     * @return this {@link Builder}
+     */
+    public Builder useBulkStmts(Boolean useBulkStmts) {
+      this.useBulkStmts = useBulkStmts;
+      return this;
+    }
+
+    /**
+     * Disable pipeline
+     *
+     * @param disablePipeline disable pipeline.
+     * @return this {@link Builder}
+     */
+    public Builder disablePipeline(Boolean disablePipeline) {
+      this.disablePipeline = disablePipeline;
+      return this;
+    }
+
+    /**
+     * Permit to force autocommit connection value
+     *
+     * @param autocommit autocommit value
+     * @return this {@link Builder}
+     */
+    public Builder autocommit(Boolean autocommit) {
+      this.autocommit = autocommit;
+      return this;
+    }
+
+    /**
+     * Permit indicating to force DatabaseMetadata.getDatabaseProductName() to return `MySQL` as
+     * database type, not real database type
+     *
+     * @param useMysqlMetadata force DatabaseMetadata.getDatabaseProductName() to return `MySQL`
+     * @return this {@link Builder}
+     */
+    public Builder useMysqlMetadata(Boolean useMysqlMetadata) {
+      this.useMysqlMetadata = useMysqlMetadata;
+      return this;
+    }
+
+    /**
+     * Create database if not exist. This is mainly for test, since does require an additional query
+     * after connection
+     *
+     * @param createDatabaseIfNotExist must driver create database if doesn't exist
+     * @return this {@link Builder}
+     */
+    public Builder createDatabaseIfNotExist(Boolean createDatabaseIfNotExist) {
+      this.createDatabaseIfNotExist = createDatabaseIfNotExist;
+      return this;
+    }
+
+    /**
+     * On dead-lock exception must add innodb status in exception error message. If enabled, an
+     * additional command will be done to retrieve innodb status when dead-lock occurs.
+     *
+     * @param includeInnodbStatusInDeadlockExceptions Must dead-lock exception must add innodb
+     *     status in exception error message
+     * @return this {@link Builder}
+     */
+    public Builder includeInnodbStatusInDeadlockExceptions(
+        Boolean includeInnodbStatusInDeadlockExceptions) {
+      this.includeInnodbStatusInDeadlockExceptions = includeInnodbStatusInDeadlockExceptions;
+      return this;
+    }
+
+    /**
+     * Dead-lock error will contain threads information
+     *
+     * @param includeThreadDumpInDeadlockExceptions must dead-lock error contain treads informations
+     * @return this {@link Builder}
+     */
+    public Builder includeThreadDumpInDeadlockExceptions(
+        Boolean includeThreadDumpInDeadlockExceptions) {
+      this.includeThreadDumpInDeadlockExceptions = includeThreadDumpInDeadlockExceptions;
+      return this;
+    }
+
+    /**
+     * set service principal name (GSSAPI)
+     *
+     * @param servicePrincipalName service principal name (GSSAPI)
+     * @return this {@link Builder}
+     */
+    public Builder servicePrincipalName(String servicePrincipalName) {
+      this.servicePrincipalName = nullOrEmpty(servicePrincipalName);
+      return this;
+    }
+
+    /**
+     * Set default fetch size
+     *
+     * @param defaultFetchSize default fetch size
+     * @return this {@link Builder}
+     */
+    public Builder defaultFetchSize(Integer defaultFetchSize) {
+      this.defaultFetchSize = defaultFetchSize;
+      return this;
+    }
+
+    /**
+     * Permit to defined default tls plugin type
+     *
+     * @param tlsSocketType default tls socket plugin to use
+     * @return this {@link Builder}
+     */
+    public Builder tlsSocketType(String tlsSocketType) {
+      this.tlsSocketType = nullOrEmpty(tlsSocketType);
+      return this;
+    }
+
+    /**
+     * Set the log size limit for query
+     *
+     * @param maxQuerySizeToLog set query size limit
+     * @return this {@link Builder}
+     */
+    public Builder maxQuerySizeToLog(Integer maxQuerySizeToLog) {
+      this.maxQuerySizeToLog = maxQuerySizeToLog;
+      return this;
+    }
+
+    /**
+     * Indicate to driver server max_allowed_packet. This permit to driver to avoid sending commands
+     * too big, that would have make server to drop connection
+     *
+     * @param maxAllowedPacket indicate server max_allowed_packet value
+     * @return this {@link Builder}
+     */
+    public Builder maxAllowedPacket(Integer maxAllowedPacket) {
+      this.maxAllowedPacket = maxAllowedPacket;
+      return this;
+    }
+
+    /**
+     * When failover occurs, how many connection attempt before throwing error when reconnecting
+     *
+     * @param retriesAllDown number of attemps to reconnect
+     * @return this {@link Builder}
+     */
+    public Builder retriesAllDown(Integer retriesAllDown) {
+      this.retriesAllDown = retriesAllDown;
+      return this;
+    }
+
+    /**
+     * Indicate galera allowed state (comma separated), permitting to validate if galera node is
+     * synchronized
+     *
+     * @param galeraAllowedState galera allowed state
+     * @return this {@link Builder}
+     */
+    public Builder galeraAllowedState(String galeraAllowedState) {
+      this.galeraAllowedState = nullOrEmpty(galeraAllowedState);
+      return this;
+    }
+
+    /**
+     * Create pool if not existing, or get a connection for the pool associate with this connection
+     * string if existing.
+     *
+     * @param pool use pool
+     * @return this {@link Builder}
+     */
+    public Builder pool(Boolean pool) {
+      this.pool = pool;
+      return this;
+    }
+
+    /**
+     * set pool name
+     *
+     * @param poolName pool name
+     * @return this {@link Builder}
+     */
+    public Builder poolName(String poolName) {
+      this.poolName = nullOrEmpty(poolName);
+      return this;
+    }
+
+    /**
+     * Set the limit number of connection in pool.
+     *
+     * @param maxPoolSize maximum connection size in pool.
+     * @return this {@link Builder}
+     */
+    public Builder maxPoolSize(Integer maxPoolSize) {
+      this.maxPoolSize = maxPoolSize;
+      return this;
+    }
+
+    /**
+     * Minimum pool size.
+     *
+     * @param minPoolSize minimum pool size
+     * @return this {@link Builder}
+     */
+    public Builder minPoolSize(Integer minPoolSize) {
+      this.minPoolSize = minPoolSize;
+      return this;
+    }
+
+    /**
+     * Set the maximum idle time of a connection indicating that connection must be released
+     *
+     * @param maxIdleTime maximum idle time of a connection in pool
+     * @return this {@link Builder}
+     */
+    public Builder maxIdleTime(Integer maxIdleTime) {
+      this.maxIdleTime = maxIdleTime;
+      return this;
+    }
+
+    /**
+     * Must pool register JMX information
+     *
+     * @param registerJmxPool register pool to JMX
+     * @return this {@link Builder}
+     */
+    public Builder registerJmxPool(Boolean registerJmxPool) {
+      this.registerJmxPool = registerJmxPool;
+      return this;
+    }
+
+    /**
+     * Pool will validate connection before giving it. This amount of time indicate that recently
+     * use connection can skip validation 0 means connection will be validated each time (even is
+     * just used)
+     *
+     * @param poolValidMinDelay time limit indicating that connection in pool must be validated
+     * @return this {@link Builder}
+     */
+    public Builder poolValidMinDelay(Integer poolValidMinDelay) {
+      this.poolValidMinDelay = poolValidMinDelay;
+      return this;
+    }
+
+    /**
+     * Indicate that connection returned to pool must be RESETed like having proper connection
+     * state.
+     *
+     * @param useResetConnection use reset connection when returning connection to pool.
+     * @return this {@link Builder}
+     */
+    public Builder useResetConnection(Boolean useResetConnection) {
+      this.useResetConnection = useResetConnection;
+      return this;
+    }
+
+    /**
+     * MySQL Authentication RSA server file, for mysql authentication
+     *
+     * @param serverRsaPublicKeyFile server RSA public key file
+     * @return this {@link Builder}
+     */
+    public Builder serverRsaPublicKeyFile(String serverRsaPublicKeyFile) {
+      this.serverRsaPublicKeyFile = nullOrEmpty(serverRsaPublicKeyFile);
+      return this;
+    }
+
+    /**
+     * Allow RSA server file retrieval from MySQL server
+     *
+     * @param allowPublicKeyRetrieval Allow RSA server file retrieval from MySQL server
+     * @return this {@link Builder}
+     */
+    public Builder allowPublicKeyRetrieval(Boolean allowPublicKeyRetrieval) {
+      this.allowPublicKeyRetrieval = allowPublicKeyRetrieval;
+      return this;
+    }
+
+    /**
+     * Cache all socket available information.
+     *
+     * @param useReadAheadInput cache available socket data when reading socket.
+     * @return this {@link Builder}
+     */
+    public Builder useReadAheadInput(Boolean useReadAheadInput) {
+      this.useReadAheadInput = useReadAheadInput;
+      return this;
+    }
+
+    /**
+     * Cache server prepare result
+     *
+     * @param cachePrepStmts cache server prepared result
+     * @return this {@link Builder}
+     */
+    public Builder cachePrepStmts(Boolean cachePrepStmts) {
+      this.cachePrepStmts = cachePrepStmts;
+      return this;
+    }
+
+    /**
+     * Must cache commands in transaction and replay transaction on failover.
+     *
+     * @param transactionReplay cache transaction and replay on failover
+     * @return this {@link Builder}
+     */
+    public Builder transactionReplay(Boolean transactionReplay) {
+      this.transactionReplay = transactionReplay;
+      return this;
+    }
+
+    /**
+     * Transaction replay cache size
+     *
+     * @param transactionReplaySize transaction replay cache size
+     * @return this {@link Builder}
+     */
+    public Builder transactionReplaySize(Integer transactionReplaySize) {
+      this.transactionReplaySize = transactionReplaySize;
+      return this;
+    }
+
+    /**
+     * Build a configuration
+     *
+     * @return a Configuration object
+     * @throws SQLException if option data type doesn't correspond
+     */
+    public Configuration build() throws SQLException {
+      Configuration conf =
+          new Configuration(
+              this.database,
+              this._addresses,
+              this._haMode,
+              this.user,
+              this.password,
+              this.enabledSslProtocolSuites,
+              this.socketFactory,
+              this.connectTimeout,
+              this.pipe,
+              this.localSocket,
+              this.tcpKeepAlive,
+              this.uuidAsString,
+              this.tcpKeepIdle,
+              this.tcpKeepCount,
+              this.tcpKeepInterval,
+              this.tcpAbortiveClose,
+              this.localSocketAddress,
+              this.socketTimeout,
+              this.allowMultiQueries,
+              this.allowLocalInfile,
+              this.useCompression,
+              this.blankTableNameMeta,
+              this.credentialType,
+              this.sslMode,
+              this.transactionIsolation,
+              this.enabledSslCipherSuites,
+              this.sessionVariables,
+              this.tinyInt1isBit,
+              this.transformedBitIsBoolean,
+              this.yearIsDateType,
+              this.timezone,
+              this.dumpQueriesOnException,
+              this.prepStmtCacheSize,
+              this.useAffectedRows,
+              this.useServerPrepStmts,
+              this.connectionAttributes,
+              this.useBulkStmts,
+              this.disablePipeline,
+              this.autocommit,
+              this.useMysqlMetadata,
+              this.createDatabaseIfNotExist,
+              this.includeInnodbStatusInDeadlockExceptions,
+              this.includeThreadDumpInDeadlockExceptions,
+              this.servicePrincipalName,
+              this.defaultFetchSize,
+              this.tlsSocketType,
+              this.maxQuerySizeToLog,
+              this.maxAllowedPacket,
+              this.retriesAllDown,
+              this.galeraAllowedState,
+              this.pool,
+              this.poolName,
+              this.maxPoolSize,
+              this.minPoolSize,
+              this.maxIdleTime,
+              this.registerJmxPool,
+              this.poolValidMinDelay,
+              this.useResetConnection,
+              this.serverRsaPublicKeyFile,
+              this.allowPublicKeyRetrieval,
+              this.serverSslCert,
+              this.keyStore,
+              this.keyStorePassword,
+              this.keyStoreType,
+              this.useReadAheadInput,
+              this.cachePrepStmts,
+              this.transactionReplay,
+              this.transactionReplaySize,
+              this.geometryDefaultType,
+              this.restrictedAuth,
+              this.initSql,
+              this._nonMappedOptions);
+      conf.initialUrl = buildUrl(conf);
+      return conf;
+    }
+  }
+
+  private static String nullOrEmpty(String val) {
+    return (val == null || val.isEmpty()) ? null : val;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/Connection.java b/src/main/java/org/mariadb/jdbc/Connection.java
new file mode 100644
index 0000000..e870cce
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/Connection.java
@@ -0,0 +1,933 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.*;
+import java.util.*;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.sql.ConnectionEvent;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.impl.StandardClient;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.client.ChangeDbPacket;
+import org.mariadb.jdbc.message.client.PingPacket;
+import org.mariadb.jdbc.message.client.QueryPacket;
+import org.mariadb.jdbc.message.client.ResetPacket;
+import org.mariadb.jdbc.util.NativeSql;
+import org.mariadb.jdbc.util.constants.Capabilities;
+import org.mariadb.jdbc.util.constants.ConnectionState;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Public Connection class */
+public class Connection implements java.sql.Connection {
+
+  private static final Pattern CALLABLE_STATEMENT_PATTERN =
+      Pattern.compile(
+          "^(\\s*\\{)?\\s*((\\?\\s*=)?(\\s*/\\*([^*]|\\*[^/])*\\*/)*\\s*"
+              + "call(\\s*/\\*([^*]|\\*[^/])*\\*/)*\\s*((((`[^`]+`)|([^`}]+))\\.)?"
+              + "((`[^`]+`)|([^`}(]+)))\\s*(\\(.*\\))?(\\s*/\\*([^*]|\\*[^/])*\\*/)*"
+              + "\\s*(#.*)?)\\s*(}\\s*)?$",
+          Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+  private final ReentrantLock lock;
+  private final Configuration conf;
+  private ExceptionFactory exceptionFactory;
+  private final Client client;
+  private final Properties clientInfo = new Properties();
+  private int lowercaseTableNames = -1;
+  private final AtomicInteger savepointId = new AtomicInteger();
+  private boolean readOnly;
+  private final boolean canUseServerTimeout;
+  private final boolean canCachePrepStmts;
+  private final boolean canUseServerMaxRows;
+  private final int defaultFetchSize;
+  private final boolean forceTransactionEnd;
+  private MariaDbPoolConnection poolConnection;
+
+  /**
+   * Connection construction.
+   *
+   * @param conf configuration
+   * @param lock thread safe locker
+   * @param client client object
+   */
+  public Connection(Configuration conf, ReentrantLock lock, Client client) {
+    this.conf = conf;
+    this.forceTransactionEnd =
+        Boolean.parseBoolean(conf.nonMappedOptions().getProperty("forceTransactionEnd", "false"));
+    this.lock = lock;
+    this.exceptionFactory = client.getExceptionFactory().setConnection(this);
+    this.client = client;
+    Context context = this.client.getContext();
+    this.canUseServerTimeout =
+        context.getVersion().isMariaDBServer()
+            && context.getVersion().versionGreaterOrEqual(10, 1, 2);
+    this.canUseServerMaxRows =
+        context.getVersion().isMariaDBServer()
+            && context.getVersion().versionGreaterOrEqual(10, 3, 0);
+    this.canCachePrepStmts = context.getConf().cachePrepStmts();
+    this.defaultFetchSize = context.getConf().defaultFetchSize();
+  }
+
+  /**
+   * Internal method. Indicate that connection is created from internal pool
+   *
+   * @param poolConnection PoolConnection
+   */
+  public void setPoolConnection(MariaDbPoolConnection poolConnection) {
+    this.poolConnection = poolConnection;
+    this.exceptionFactory = exceptionFactory.setPoolConnection(poolConnection);
+  }
+
+  /**
+   * Cancels the current query - clones the current protocol and executes a query using the new
+   * connection.
+   *
+   * @throws SQLException never thrown
+   */
+  public void cancelCurrentQuery() throws SQLException {
+    try (Client cli =
+        new StandardClient(conf, client.getHostAddress(), new ReentrantLock(), true)) {
+      cli.execute(new QueryPacket("KILL QUERY " + client.getContext().getThreadId()), false);
+    }
+  }
+
+  @Override
+  public Statement createStatement() {
+    return new Statement(
+        this,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        Statement.RETURN_GENERATED_KEYS,
+        ResultSet.TYPE_FORWARD_ONLY,
+        ResultSet.CONCUR_READ_ONLY,
+        defaultFetchSize);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql) throws SQLException {
+    return prepareInternal(
+        sql,
+        Statement.NO_GENERATED_KEYS,
+        ResultSet.TYPE_FORWARD_ONLY,
+        ResultSet.CONCUR_READ_ONLY,
+        conf.useServerPrepStmts());
+  }
+
+  /**
+   * Prepare statement creation
+   *
+   * @param sql sql
+   * @param autoGeneratedKeys auto generated key required
+   * @param resultSetType result-set type
+   * @param resultSetConcurrency concurrency
+   * @param useBinary use server prepare statement
+   * @return prepared statement
+   * @throws SQLException if Prepare fails
+   */
+  public PreparedStatement prepareInternal(
+      String sql,
+      int autoGeneratedKeys,
+      int resultSetType,
+      int resultSetConcurrency,
+      boolean useBinary)
+      throws SQLException {
+    checkNotClosed();
+    if (useBinary) {
+      try {
+        return new ServerPreparedStatement(
+            NativeSql.parse(sql, client.getContext()),
+            this,
+            lock,
+            canUseServerTimeout,
+            canUseServerMaxRows,
+            canCachePrepStmts,
+            autoGeneratedKeys,
+            resultSetType,
+            resultSetConcurrency,
+            defaultFetchSize);
+      } catch (SQLException e) {
+        // failover to client
+      }
+    }
+    return new ClientPreparedStatement(
+        NativeSql.parse(sql, client.getContext()),
+        this,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        autoGeneratedKeys,
+        resultSetType,
+        resultSetConcurrency,
+        defaultFetchSize);
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql) throws SQLException {
+    return prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+  }
+
+  @Override
+  public String nativeSQL(String sql) throws SQLException {
+    return NativeSql.parse(sql, client.getContext());
+  }
+
+  @Override
+  public boolean getAutoCommit() {
+    return (client.getContext().getServerStatus() & ServerStatus.AUTOCOMMIT) > 0;
+  }
+
+  @Override
+  public void setAutoCommit(boolean autoCommit) throws SQLException {
+    if (autoCommit == getAutoCommit()) {
+      return;
+    }
+    lock.lock();
+    try {
+      getContext().addStateFlag(ConnectionState.STATE_AUTOCOMMIT);
+      client.execute(
+          new QueryPacket(((autoCommit) ? "set autocommit=1" : "set autocommit=0")), true);
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public void commit() throws SQLException {
+    lock.lock();
+    try {
+      if (forceTransactionEnd
+          || (client.getContext().getServerStatus() & ServerStatus.IN_TRANSACTION) > 0) {
+        client.execute(new QueryPacket("COMMIT"), false);
+      }
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public void rollback() throws SQLException {
+    lock.lock();
+    try {
+      if (forceTransactionEnd
+          || (client.getContext().getServerStatus() & ServerStatus.IN_TRANSACTION) > 0) {
+        client.execute(new QueryPacket("ROLLBACK"), true);
+      }
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public void close() throws SQLException {
+    if (poolConnection != null) {
+      poolConnection.fireConnectionClosed(new ConnectionEvent(poolConnection));
+      return;
+    }
+    client.close();
+  }
+
+  @Override
+  public boolean isClosed() {
+    return client.isClosed();
+  }
+
+  /**
+   * Connection context.
+   *
+   * @return connection context.
+   */
+  public Context getContext() {
+    return client.getContext();
+  }
+
+  /**
+   * Are table case-sensitive or not . Default Value: 0 (Unix), 1 (Windows), 2 (Mac OS X). If set to
+   * 0 (the default on Unix-based systems), table names and aliases and database names are compared
+   * in a case-sensitive manner. If set to 1 (the default on Windows), names are stored in lowercase
+   * and not compared in a case-sensitive manner. If set to 2 (the default on Mac OS X), names are
+   * stored as declared, but compared in lowercase.
+   *
+   * @return int value.
+   * @throws SQLException if a connection error occur
+   */
+  public int getLowercaseTableNames() throws SQLException {
+    if (lowercaseTableNames == -1) {
+      try (java.sql.Statement st = createStatement()) {
+        try (ResultSet rs = st.executeQuery("select @@lower_case_table_names")) {
+          rs.next();
+          lowercaseTableNames = rs.getInt(1);
+        }
+      }
+    }
+    return lowercaseTableNames;
+  }
+
+  @Override
+  public DatabaseMetaData getMetaData() {
+    return new DatabaseMetaData(this, this.conf);
+  }
+
+  @Override
+  public boolean isReadOnly() {
+    return this.readOnly;
+  }
+
+  @Override
+  public void setReadOnly(boolean readOnly) throws SQLException {
+    lock.lock();
+    try {
+      if (this.readOnly != readOnly) {
+        client.setReadOnly(readOnly);
+      }
+      this.readOnly = readOnly;
+      getContext().addStateFlag(ConnectionState.STATE_READ_ONLY);
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public String getCatalog() throws SQLException {
+
+    if (client.getContext().hasClientCapability(Capabilities.CLIENT_SESSION_TRACK)) {
+      return client.getContext().getDatabase();
+    }
+
+    Statement stmt = createStatement();
+    ResultSet rs = stmt.executeQuery("select database()");
+    rs.next();
+    client.getContext().setDatabase(rs.getString(1));
+    return client.getContext().getDatabase();
+  }
+
+  @Override
+  public void setCatalog(String catalog) throws SQLException {
+    // null catalog means keep current.
+    // there is no possibility to set no database when one is selected
+    if (catalog == null
+        || (client.getContext().hasClientCapability(Capabilities.CLIENT_SESSION_TRACK)
+            && catalog.equals(client.getContext().getDatabase()))) {
+      return;
+    }
+    lock.lock();
+    try {
+      getContext().addStateFlag(ConnectionState.STATE_DATABASE);
+      client.execute(new ChangeDbPacket(catalog), true);
+      client.getContext().setDatabase(catalog);
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public int getTransactionIsolation() throws SQLException {
+
+    String sql = "SELECT @@tx_isolation";
+
+    if (!client.getContext().getVersion().isMariaDBServer()) {
+      if ((client.getContext().getVersion().getMajorVersion() >= 8
+              && client.getContext().getVersion().versionGreaterOrEqual(8, 0, 3))
+          || (client.getContext().getVersion().getMajorVersion() < 8
+              && client.getContext().getVersion().versionGreaterOrEqual(5, 7, 20))) {
+        sql = "SELECT @@transaction_isolation";
+      }
+    }
+
+    ResultSet rs = createStatement().executeQuery(sql);
+    if (rs.next()) {
+      final String response = rs.getString(1);
+      switch (response) {
+        case "REPEATABLE-READ":
+          return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
+
+        case "READ-UNCOMMITTED":
+          return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
+
+        case "READ-COMMITTED":
+          return java.sql.Connection.TRANSACTION_READ_COMMITTED;
+
+        case "SERIALIZABLE":
+          return java.sql.Connection.TRANSACTION_SERIALIZABLE;
+
+        default:
+          throw exceptionFactory.create(
+              String.format(
+                  "Could not get transaction isolation level: Invalid value \"%s\"", response));
+      }
+    }
+    throw exceptionFactory.create("Failed to retrieve transaction isolation");
+  }
+
+  @Override
+  public void setTransactionIsolation(int level) throws SQLException {
+    String query = "SET SESSION TRANSACTION ISOLATION LEVEL";
+    switch (level) {
+      case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
+        query += " READ UNCOMMITTED";
+        break;
+      case java.sql.Connection.TRANSACTION_READ_COMMITTED:
+        query += " READ COMMITTED";
+        break;
+      case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
+        query += " REPEATABLE READ";
+        break;
+      case java.sql.Connection.TRANSACTION_SERIALIZABLE:
+        query += " SERIALIZABLE";
+        break;
+      default:
+        throw new SQLException("Unsupported transaction isolation level");
+    }
+    lock.lock();
+    try {
+      checkNotClosed();
+      getContext().addStateFlag(ConnectionState.STATE_TRANSACTION_ISOLATION);
+      client.getContext().setTransactionIsolationLevel(level);
+      client.execute(new QueryPacket(query), true);
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    checkNotClosed();
+    if (client.getContext().getWarning() == 0) {
+      return null;
+    }
+
+    SQLWarning last = null;
+    SQLWarning first = null;
+
+    try (Statement st = this.createStatement()) {
+      try (ResultSet rs = st.executeQuery("show warnings")) {
+        // returned result set has 'level', 'code' and 'message' columns, in this order.
+        while (rs.next()) {
+          int code = rs.getInt(2);
+          String message = rs.getString(3);
+          SQLWarning warning = new SQLWarning(message, null, code);
+          if (first == null) {
+            first = warning;
+          } else {
+            last.setNextWarning(warning);
+          }
+          last = warning;
+        }
+      }
+    }
+    return first;
+  }
+
+  @Override
+  public void clearWarnings() {
+    client.getContext().setWarning(0);
+  }
+
+  @Override
+  public Statement createStatement(int resultSetType, int resultSetConcurrency)
+      throws SQLException {
+    checkNotClosed();
+    return new Statement(
+        this,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        Statement.RETURN_GENERATED_KEYS,
+        resultSetType,
+        resultSetConcurrency,
+        defaultFetchSize);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
+      throws SQLException {
+    return prepareInternal(
+        sql,
+        Statement.RETURN_GENERATED_KEYS,
+        resultSetType,
+        resultSetConcurrency,
+        conf.useServerPrepStmts());
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
+      throws SQLException {
+    checkNotClosed();
+    Matcher matcher = CALLABLE_STATEMENT_PATTERN.matcher(sql);
+    if (!matcher.matches()) {
+      throw new SQLSyntaxErrorException(
+          "invalid callable syntax. must be like {[?=]call <procedure/function name>[(?,?, ...)]}\n"
+              + " but was : "
+              + sql);
+    }
+
+    String query = NativeSql.parse(matcher.group(2), client.getContext());
+
+    boolean isFunction = (matcher.group(3) != null);
+    String databaseAndProcedure = matcher.group(8);
+    String database = matcher.group(10);
+    String procedureName = matcher.group(13);
+    String arguments = matcher.group(16);
+    if (database == null) {
+      database = getCatalog();
+    }
+
+    if (isFunction) {
+      return new FunctionStatement(
+          this,
+          database,
+          databaseAndProcedure,
+          (arguments == null) ? "()" : arguments,
+          lock,
+          canUseServerTimeout,
+          canUseServerMaxRows,
+          canCachePrepStmts,
+          resultSetType,
+          resultSetConcurrency);
+    } else {
+      return new ProcedureStatement(
+          this,
+          query,
+          database,
+          procedureName,
+          lock,
+          canUseServerTimeout,
+          canUseServerMaxRows,
+          canCachePrepStmts,
+          resultSetType,
+          resultSetConcurrency);
+    }
+  }
+
+  @Override
+  public Map<String, Class<?>> getTypeMap() {
+    return new HashMap<>();
+  }
+
+  @Override
+  public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+    throw exceptionFactory.notSupported("TypeMap are not supported");
+  }
+
+  @Override
+  public int getHoldability() {
+    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+  @Override
+  public void setHoldability(int holdability) {
+    // not supported
+  }
+
+  @Override
+  public Savepoint setSavepoint() throws SQLException {
+    MariaDbSavepoint savepoint = new MariaDbSavepoint(savepointId.incrementAndGet());
+    client.execute(new QueryPacket("SAVEPOINT `" + savepoint.rawValue() + "`"), true);
+    return savepoint;
+  }
+
+  @Override
+  public Savepoint setSavepoint(String name) throws SQLException {
+    MariaDbSavepoint savepoint = new MariaDbSavepoint(name.replace("`", "``"));
+    client.execute(new QueryPacket("SAVEPOINT `" + savepoint.rawValue() + "`"), true);
+    return savepoint;
+  }
+
+  @Override
+  public void rollback(java.sql.Savepoint savepoint) throws SQLException {
+    checkNotClosed();
+    lock.lock();
+    try {
+      if ((client.getContext().getServerStatus() & ServerStatus.IN_TRANSACTION) > 0) {
+        if (savepoint instanceof Connection.MariaDbSavepoint) {
+          client.execute(
+              new QueryPacket(
+                  "ROLLBACK TO SAVEPOINT `"
+                      + ((Connection.MariaDbSavepoint) savepoint).rawValue()
+                      + "`"),
+              true);
+        } else {
+          throw exceptionFactory.create("Unknown savepoint type");
+        }
+      }
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException {
+    checkNotClosed();
+    lock.lock();
+    try {
+      if ((client.getContext().getServerStatus() & ServerStatus.IN_TRANSACTION) > 0) {
+        if (savepoint instanceof Connection.MariaDbSavepoint) {
+          client.execute(
+              new QueryPacket(
+                  "RELEASE SAVEPOINT `"
+                      + ((Connection.MariaDbSavepoint) savepoint).rawValue()
+                      + "`"),
+              true);
+        } else {
+          throw exceptionFactory.create("Unknown savepoint type");
+        }
+      }
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public Statement createStatement(
+      int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+    checkNotClosed();
+    return new Statement(
+        this,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        Statement.NO_GENERATED_KEYS,
+        resultSetType,
+        resultSetConcurrency,
+        defaultFetchSize);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(
+      String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+      throws SQLException {
+    return prepareStatement(sql, resultSetType, resultSetConcurrency);
+  }
+
+  @Override
+  public CallableStatement prepareCall(
+      String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+      throws SQLException {
+    return prepareCall(sql, resultSetType, resultSetConcurrency);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+    return prepareInternal(
+        sql,
+        autoGeneratedKeys,
+        ResultSet.TYPE_FORWARD_ONLY,
+        ResultSet.CONCUR_READ_ONLY,
+        conf.useServerPrepStmts());
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
+    return prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
+    return prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
+  }
+
+  @Override
+  public Clob createClob() {
+    return new MariaDbClob();
+  }
+
+  @Override
+  public Blob createBlob() {
+    return new MariaDbBlob();
+  }
+
+  @Override
+  public NClob createNClob() {
+    return new MariaDbClob();
+  }
+
+  @Override
+  public SQLXML createSQLXML() throws SQLException {
+    throw exceptionFactory.notSupported("SQLXML type is not supported");
+  }
+
+  private void checkNotClosed() throws SQLException {
+    if (client.isClosed()) {
+      throw exceptionFactory.create("Connection is closed", "08000", 1220);
+    }
+  }
+
+  @Override
+  public boolean isValid(int timeout) throws SQLException {
+    if (timeout < 0) {
+      throw exceptionFactory.create("the value supplied for timeout is negative");
+    }
+    lock.lock();
+    try {
+      client.execute(PingPacket.INSTANCE, true);
+      return true;
+    } catch (SQLException sqle) {
+      if (poolConnection != null) {
+        MariaDbPoolConnection poolConnection = this.poolConnection;
+        poolConnection.fireConnectionErrorOccurred(sqle);
+        poolConnection.close();
+      }
+      return false;
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public void setClientInfo(String name, String value) {
+    clientInfo.put(name, value);
+  }
+
+  @Override
+  public String getClientInfo(String name) {
+    return (String) clientInfo.get(name);
+  }
+
+  @Override
+  public Properties getClientInfo() {
+    return clientInfo;
+  }
+
+  @Override
+  public void setClientInfo(Properties properties) {
+    clientInfo.putAll(properties);
+  }
+
+  @Override
+  public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+    throw exceptionFactory.notSupported("Array type is not supported");
+  }
+
+  @Override
+  public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+    throw exceptionFactory.notSupported("Struct type is not supported");
+  }
+
+  @Override
+  public String getSchema() {
+    // We support only catalog
+    return null;
+  }
+
+  @Override
+  public void setSchema(String schema) {
+    // We support only catalog, and JDBC indicate "If the driver does not support schemas, it will
+    // silently ignore this request."
+  }
+
+  @Override
+  public void abort(Executor executor) throws SQLException {
+    if (poolConnection != null) {
+      MariaDbPoolConnection poolConnection = this.poolConnection;
+      poolConnection.close();
+      return;
+    }
+    client.abort(executor);
+  }
+
+  @Override
+  public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+    if (this.isClosed()) {
+      throw exceptionFactory.create(
+          "Connection.setNetworkTimeout cannot be called on a closed connection");
+    }
+    if (milliseconds < 0) {
+      throw exceptionFactory.create(
+          "Connection.setNetworkTimeout cannot be called with a negative timeout");
+    }
+    getContext().addStateFlag(ConnectionState.STATE_NETWORK_TIMEOUT);
+
+    lock.lock();
+    try {
+      client.setSocketTimeout(milliseconds);
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public int getNetworkTimeout() {
+    return client.getSocketTimeout();
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+
+  /**
+   * Associate connection client
+   *
+   * @return connection client
+   */
+  public Client getClient() {
+    return client;
+  }
+
+  /** Internal Savepoint implementation */
+  class MariaDbSavepoint implements java.sql.Savepoint {
+
+    private final String name;
+    private final Integer id;
+
+    public MariaDbSavepoint(final String name) {
+      this.name = name;
+      this.id = null;
+    }
+
+    public MariaDbSavepoint(final int savepointId) {
+      this.id = savepointId;
+      this.name = null;
+    }
+
+    /**
+     * Retrieves the generated ID for the savepoint that this <code>Savepoint</code> object
+     * represents.
+     *
+     * @return the numeric ID of this savepoint
+     */
+    public int getSavepointId() throws SQLException {
+      if (name != null) {
+        throw exceptionFactory.create("Cannot retrieve savepoint id of a named savepoint");
+      }
+      return id;
+    }
+
+    /**
+     * Retrieves the name of the savepoint that this <code>Savepoint</code> object represents.
+     *
+     * @return the name of this savepoint
+     */
+    public String getSavepointName() throws SQLException {
+      if (id != null) {
+        throw exceptionFactory.create("Cannot retrieve savepoint name of an unnamed savepoint");
+      }
+      return name;
+    }
+
+    public String rawValue() {
+      if (id != null) {
+        return "_jid_" + id;
+      }
+      return name;
+    }
+  }
+
+  /**
+   * Reset connection set has it was after creating a "fresh" new connection.
+   * defaultTransactionIsolation must have been initialized.
+   *
+   * <p>BUT : - session variable state are reset only if option useResetConnection is set and - if
+   * using the option "useServerPrepStmts", PREPARE statement are still prepared
+   *
+   * @throws SQLException if resetting operation failed
+   */
+  public void reset() throws SQLException {
+    // COM_RESET_CONNECTION exist since mysql 5.7.3 and mariadb 10.2.4
+    // but not possible to use it with mysql waiting for https://bugs.mysql.com/bug.php?id=97633
+    // correction.
+    // and mariadb only since https://jira.mariadb.org/browse/MDEV-18281
+    boolean useComReset =
+        conf.useResetConnection()
+            && getContext().getVersion().isMariaDBServer()
+            && (getContext().getVersion().versionGreaterOrEqual(10, 3, 13)
+                || (getContext().getVersion().getMajorVersion() == 10
+                    && getContext().getVersion().getMinorVersion() == 2
+                    && getContext().getVersion().versionGreaterOrEqual(10, 2, 22)));
+
+    if (useComReset) {
+      client.execute(ResetPacket.INSTANCE, true);
+    }
+
+    // in transaction => rollback
+    if (forceTransactionEnd
+        || (client.getContext().getServerStatus() & ServerStatus.IN_TRANSACTION) > 0) {
+      client.execute(new QueryPacket("ROLLBACK"), true);
+    }
+
+    int stateFlag = getContext().getStateFlag();
+    if (stateFlag != 0) {
+      try {
+        if ((stateFlag & ConnectionState.STATE_NETWORK_TIMEOUT) != 0) {
+          setNetworkTimeout(null, conf.socketTimeout());
+        }
+        if ((stateFlag & ConnectionState.STATE_AUTOCOMMIT) != 0) {
+          setAutoCommit(conf.autocommit() == null ? true : conf.autocommit());
+        }
+        if ((stateFlag & ConnectionState.STATE_DATABASE) != 0) {
+          setCatalog(conf.database());
+        }
+        if ((stateFlag & ConnectionState.STATE_READ_ONLY) != 0) {
+          setReadOnly(false); // default to master connection
+        }
+        if (!useComReset && (stateFlag & ConnectionState.STATE_TRANSACTION_ISOLATION) != 0) {
+          setTransactionIsolation(
+              conf.transactionIsolation() == null
+                  ? java.sql.Connection.TRANSACTION_REPEATABLE_READ
+                  : conf.transactionIsolation().getLevel());
+        }
+      } catch (SQLException sqle) {
+        throw exceptionFactory.create("error resetting connection");
+      }
+    }
+
+    client.reset();
+
+    clearWarnings();
+  }
+
+  /**
+   * Current server thread id.
+   *
+   * @return current server thread id
+   */
+  public long getThreadId() {
+    return client.getContext().getThreadId();
+  }
+
+  /**
+   * Fire event to indicate to StatementEventListeners registered on the connection that a
+   * PreparedStatement is closed.
+   *
+   * @param prep prepare statement closing
+   */
+  public void fireStatementClosed(PreparedStatement prep) {
+    if (poolConnection != null) {
+      poolConnection.fireStatementClosed(prep);
+    }
+  }
+
+  /**
+   * Get connection exception factory
+   *
+   * @return connection exception factory
+   */
+  protected ExceptionFactory getExceptionFactory() {
+    return exceptionFactory;
+  }
+
+  /**
+   * for _TEST_ only
+   *
+   * @return current host
+   */
+  public String __test_host() {
+    return this.client.getHostAddress().toString();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/DatabaseMetaData.java b/src/main/java/org/mariadb/jdbc/DatabaseMetaData.java
new file mode 100644
index 0000000..a4bf275
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/DatabaseMetaData.java
@@ -0,0 +1,3885 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.*;
+import java.sql.Statement;
+import java.text.ParseException;
+import java.util.*;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ServerVersion;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.client.result.Result;
+import org.mariadb.jdbc.util.VersionFactory;
+import org.mariadb.jdbc.util.constants.ColumnFlags;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Mariadb Database metadata */
+public class DatabaseMetaData implements java.sql.DatabaseMetaData {
+
+  /** MariaDB driver name */
+  public static final String DRIVER_NAME = "MariaDB Connector/J";
+
+  private final org.mariadb.jdbc.Connection connection;
+  private final Configuration conf;
+
+  /**
+   * Constructor.
+   *
+   * @param connection connection
+   * @param conf configuration
+   */
+  public DatabaseMetaData(org.mariadb.jdbc.Connection connection, Configuration conf) {
+    this.connection = connection;
+    this.conf = conf;
+  }
+
+  private static String DataTypeClause(Configuration conf) {
+    String upperCaseWithoutSize =
+        " UCASE(IF( COLUMN_TYPE LIKE '%(%)%', CONCAT(SUBSTRING( COLUMN_TYPE,1, LOCATE('(',"
+            + "COLUMN_TYPE) - 1 ), SUBSTRING(COLUMN_TYPE ,1+locate(')', COLUMN_TYPE))), "
+            + "COLUMN_TYPE))";
+
+    if (conf.tinyInt1isBit()) {
+      upperCaseWithoutSize =
+          " IF(COLUMN_TYPE like 'tinyint(1)%', '"
+              + (conf.transformedBitIsBoolean() ? "BOOLEAN" : "BIT")
+              + "', "
+              + upperCaseWithoutSize
+              + ")";
+    }
+
+    if (!conf.yearIsDateType()) {
+      return " IF(COLUMN_TYPE IN ('year(2)', 'year(4)'), 'SMALLINT', " + upperCaseWithoutSize + ")";
+    }
+
+    return upperCaseWithoutSize;
+  }
+
+  // Extract identifier quoted string from input String.
+  // Return new position, or -1 on error
+  private static int skipWhiteSpace(char[] part, int startPos) {
+    for (int i = startPos; i < part.length; i++) {
+      if (!Character.isWhitespace(part[i])) {
+        return i;
+      }
+    }
+    return part.length;
+  }
+
+  private static int parseIdentifier(char[] part, int startPos, Identifier identifier)
+      throws ParseException {
+    int pos = skipWhiteSpace(part, startPos);
+    if (part[pos] != '`') {
+      throw new ParseException(new String(part), pos);
+    }
+    pos++;
+    StringBuilder sb = new StringBuilder();
+    int quotes = 0;
+    for (; pos < part.length; pos++) {
+      char ch = part[pos];
+      if (ch == '`') {
+        quotes++;
+      } else {
+        for (int j = 0; j < quotes / 2; j++) {
+          sb.append('`');
+        }
+        if (quotes % 2 == 1) {
+          if (ch == '.') {
+            if (identifier.schema != null) {
+              throw new ParseException(new String(part), pos);
+            }
+            identifier.schema = sb.toString();
+            return parseIdentifier(part, pos + 1, identifier);
+          }
+          identifier.name = sb.toString();
+          return pos;
+        }
+        quotes = 0;
+        sb.append(ch);
+      }
+    }
+    throw new ParseException(new String(part), startPos);
+  }
+
+  private static int skipKeyword(char[] part, int startPos, String keyword) throws ParseException {
+    int pos = skipWhiteSpace(part, startPos);
+    for (int i = 0; i < keyword.length(); i++, pos++) {
+      if (part[pos] != keyword.charAt(i)) {
+        throw new ParseException(new String(part), pos);
+      }
+    }
+    return pos;
+  }
+
+  private static int getImportedKeyAction(String actionKey) {
+    if (actionKey == null) {
+      return java.sql.DatabaseMetaData.importedKeyRestrict;
+    }
+    switch (actionKey) {
+      case "NO ACTION":
+        return java.sql.DatabaseMetaData.importedKeyNoAction;
+
+      case "CASCADE":
+        return java.sql.DatabaseMetaData.importedKeyCascade;
+
+      case "SET NULL":
+        return java.sql.DatabaseMetaData.importedKeySetNull;
+
+      case "SET DEFAULT":
+        return java.sql.DatabaseMetaData.importedKeySetDefault;
+
+      case "RESTRICT":
+        return java.sql.DatabaseMetaData.importedKeyRestrict;
+
+      default:
+        throw new IllegalArgumentException("Illegal key action '" + actionKey + "' specified.");
+    }
+  }
+
+  private static String quoteIdentifier(String string) {
+    return "`" + string.replaceAll("`", "``") + "`";
+  }
+
+  /**
+   * Escape String.
+   *
+   * @param value value to escape
+   * @param noBackslashEscapes must backslash be escaped
+   * @return escaped string.
+   */
+  public static String escapeString(String value, boolean noBackslashEscapes) {
+    if (noBackslashEscapes) {
+      return value.replace("'", "''");
+    }
+    return value
+        .replace("\\", "\\\\")
+        .replace("'", "\\'")
+        .replace("\0", "\\0")
+        .replace("\"", "\\\"");
+  }
+
+  private int parseIdentifierList(char[] part, int startPos, List<Identifier> list)
+      throws ParseException {
+    int pos = skipWhiteSpace(part, startPos);
+    if (part[pos] != '(') {
+      throw new ParseException(new String(part), pos);
+    }
+    pos++;
+    for (; ; ) {
+      pos = skipWhiteSpace(part, pos);
+      char ch = part[pos];
+      switch (ch) {
+        case ')':
+          return pos + 1;
+        case '`':
+          Identifier id = new Identifier();
+          pos = parseIdentifier(part, pos, id);
+          list.add(id);
+          break;
+        case ',':
+          pos++;
+          break;
+        default:
+          throw new ParseException(new String(part, startPos, part.length - startPos), startPos);
+      }
+    }
+  }
+
+  /**
+   * Get imported keys.
+   *
+   * @param tableDef table definition
+   * @param tableName table name
+   * @param catalog catalog
+   * @param connection connection
+   * @return resultset resultset
+   * @throws ParseException exception
+   */
+  private ResultSet getImportedKeys(
+      String tableDef, String tableName, String catalog, org.mariadb.jdbc.Connection connection)
+      throws Exception, SQLException {
+    boolean importedKeysWithConstraintNames =
+        Boolean.parseBoolean(
+            conf.nonMappedOptions().getProperty("importedKeysWithConstraintNames", "true"));
+    String[] columnNames = {
+      "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
+      "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
+      "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
+      "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
+      "PK_NAME", "DEFERRABILITY"
+    };
+    DataType[] dataTypes = {
+      DataType.VARCHAR, DataType.NULL, DataType.VARCHAR,
+      DataType.VARCHAR, DataType.VARCHAR, DataType.NULL,
+      DataType.VARCHAR, DataType.VARCHAR, DataType.SMALLINT,
+      DataType.SMALLINT, DataType.SMALLINT, DataType.VARCHAR,
+      DataType.VARCHAR, DataType.SMALLINT
+    };
+
+    String[] parts = tableDef.split("\n");
+
+    List<String[]> data = new ArrayList<>();
+
+    for (String part : parts) {
+      part = part.trim();
+      if (!part.toUpperCase(Locale.ROOT).startsWith("CONSTRAINT")
+          && !part.toUpperCase(Locale.ROOT).contains("FOREIGN KEY")) {
+        continue;
+      }
+      char[] partChar = part.toCharArray();
+
+      Identifier constraintName = new Identifier();
+
+      int pos = skipKeyword(partChar, 0, "CONSTRAINT");
+      pos = parseIdentifier(partChar, pos, constraintName);
+      pos = skipKeyword(partChar, pos, "FOREIGN KEY");
+      List<Identifier> foreignKeyCols = new ArrayList<>();
+      pos = parseIdentifierList(partChar, pos, foreignKeyCols);
+      pos = skipKeyword(partChar, pos, "REFERENCES");
+      Identifier pkTable = new Identifier();
+      pos = parseIdentifier(partChar, pos, pkTable);
+      List<Identifier> primaryKeyCols = new ArrayList<>();
+      parseIdentifierList(partChar, pos, primaryKeyCols);
+
+      int onUpdateReferenceAction = java.sql.DatabaseMetaData.importedKeyRestrict;
+      int onDeleteReferenceAction = java.sql.DatabaseMetaData.importedKeyRestrict;
+
+      for (String referenceAction :
+          new String[] {"RESTRICT", "CASCADE", "SET NULL", "NO ACTION", "SET DEFAULT"}) {
+        if (part.toUpperCase(Locale.ROOT).contains("ON UPDATE " + referenceAction)) {
+          onUpdateReferenceAction = getImportedKeyAction(referenceAction);
+        }
+        if (part.toUpperCase(Locale.ROOT).contains("ON DELETE " + referenceAction)) {
+          onDeleteReferenceAction = getImportedKeyAction(referenceAction);
+        }
+      }
+      Map<String, Map<String[], String>> externalInfos = new HashMap<>();
+      for (int i = 0; i < primaryKeyCols.size(); i++) {
+
+        String[] row = new String[columnNames.length];
+        row[0] = pkTable.schema; // PKTABLE_CAT
+        if (row[0] == null) {
+          row[0] = catalog;
+        }
+        row[1] = null; // PKTABLE_SCHEM
+        row[2] = pkTable.name; // PKTABLE_NAME
+        row[3] = primaryKeyCols.get(i).name; // PKCOLUMN_NAME
+        row[4] = catalog; // FKTABLE_CAT
+        row[5] = null; // FKTABLE_SCHEM
+        row[6] = tableName; // FKTABLE_NAME
+        row[7] = foreignKeyCols.get(i).name; // FKCOLUMN_NAME
+        row[8] = Integer.toString(i + 1); // KEY_SEQ
+        row[9] = Integer.toString(onUpdateReferenceAction); // UPDATE_RULE
+        row[10] = Integer.toString(onDeleteReferenceAction); // DELETE_RULE
+        row[11] = constraintName.name; // FK_NAME
+        if (importedKeysWithConstraintNames) {
+          String ext =
+              (pkTable.schema == null ? "" : quoteIdentifier(pkTable.schema) + ".")
+                  + quoteIdentifier(pkTable.name);
+          if (!externalInfos.containsKey(ext)) {
+            externalInfos.put(ext, getExtImportedKeys(ext, connection));
+          }
+          row[12] = null; // PK_NAME
+          Map<String[], String> externalInfo = externalInfos.get(ext);
+          if (externalInfo != null) {
+            for (Map.Entry<String[], String> entry : externalInfo.entrySet()) {
+              boolean foundAll = true;
+
+              for (String keyPart : entry.getKey()) {
+                boolean foundKey = false;
+                for (Identifier keyCol : primaryKeyCols) {
+                  if (keyCol.name.equals(keyPart)) {
+                    foundKey = true;
+                    break;
+                  }
+                }
+                if (!foundKey) foundAll = false;
+              }
+              if (foundAll) {
+                row[12] = entry.getValue();
+              }
+            }
+          }
+        } else {
+          row[12] = null; // PK_NAME
+        }
+        row[13] = Integer.toString(DatabaseMetaData.importedKeyNotDeferrable); // DEFERRABILITY
+        data.add(row);
+      }
+    }
+    String[][] arr = data.toArray(new String[0][]);
+
+    /* Sort array by PKTABLE_CAT, PKTABLE_NAME, and KEY_SEQ.*/
+    Arrays.sort(
+        arr,
+        (row1, row2) -> {
+          int result = row1[0].compareTo(row2[0]); // PKTABLE_CAT
+          if (result == 0) {
+            result = row1[2].compareTo(row2[2]); // PKTABLE_NAME
+            if (result == 0) {
+              result = row1[8].length() - row2[8].length(); // KEY_SEQ
+              if (result == 0) {
+                result = row1[8].compareTo(row2[8]);
+              }
+            }
+          }
+          return result;
+        });
+    return CompleteResult.createResultSet(
+        columnNames, dataTypes, arr, connection.getContext(), ColumnFlags.PRIMARY_KEY);
+  }
+
+  private Map<String[], String> getExtImportedKeys(
+      String tableName, org.mariadb.jdbc.Connection connection) throws SQLException {
+    ResultSet rs = connection.createStatement().executeQuery("SHOW CREATE TABLE " + tableName);
+    rs.next();
+    String refTableDef = rs.getString(2);
+    Map<String[], String> res = new HashMap<>();
+    String[] parts = refTableDef.split("\n");
+    for (int i = 1; i < parts.length - 1; i++) {
+      String part = parts[i].trim();
+      if (part.startsWith("`")) {
+        // field
+        continue;
+      }
+      if (part.startsWith("PRIMARY KEY") || part.startsWith("UNIQUE KEY")) {
+        String name = "PRIMARY";
+        if (part.indexOf("`") < part.indexOf("(")) {
+          int offset = part.indexOf("`");
+          name = part.substring(offset + 1, part.indexOf("`", offset + 1));
+        }
+
+        String subPart = part.substring(part.indexOf("(") + 1, part.lastIndexOf(")"));
+        List<String> cols = new ArrayList<>();
+        int pos = 0;
+        while (pos < subPart.length()) {
+          pos = subPart.indexOf("`", pos);
+          int endpos = subPart.indexOf("`", pos + 1);
+          cols.add(subPart.substring(pos + 1, endpos));
+          pos = endpos + 1;
+        }
+        res.put(cols.toArray(new String[0]), name);
+      }
+    }
+    return res;
+  }
+
+  /**
+   * Retrieves a description of the primary key columns that are referenced by the given table's
+   * foreign key columns (the primary keys imported by a table). They are ordered by PKTABLE_CAT,
+   * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
+   *
+   * <p>Each primary key column description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>PKTABLE_CAT</B> String {@code =>} primary key table catalog being imported (may be
+   *       <code>null</code>)
+   *   <LI><B>PKTABLE_SCHEM</B> String {@code =>} primary key table schema being imported (may be
+   *       <code>null</code>)
+   *   <LI><B>PKTABLE_NAME</B> String {@code =>} primary key table name being imported
+   *   <LI><B>PKCOLUMN_NAME</B> String {@code =>} primary key column name being imported
+   *   <LI><B>FKTABLE_CAT</B> String {@code =>} foreign key table catalog (may be <code>null</code>)
+   *   <LI><B>FKTABLE_SCHEM</B> String {@code =>} foreign key table schema (may be <code>null</code>
+   *       )
+   *   <LI><B>FKTABLE_NAME</B> String {@code =>} foreign key table name
+   *   <LI><B>FKCOLUMN_NAME</B> String {@code =>} foreign key column name
+   *   <LI><B>KEY_SEQ</B> short {@code =>} sequence number within a foreign key( a value of 1
+   *       represents the first column of the foreign key, a value of 2 would represent the second
+   *       column within the foreign key).
+   *   <LI><B>UPDATE_RULE</B> short {@code =>} What happens to a foreign key when the primary key is
+   *       updated:
+   *       <UL>
+   *         <LI>importedNoAction - do not allow update of primary key if it has been imported
+   *         <LI>importedKeyCascade - change imported key to agree with primary key update
+   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
+   *             has been updated
+   *         <LI>importedKeySetDefault - change imported key to default values if its primary key
+   *             has been updated
+   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
+   *       </UL>
+   *   <LI><B>DELETE_RULE</B> short {@code =>} What happens to the foreign key when primary is
+   *       deleted.
+   *       <UL>
+   *         <LI>importedKeyNoAction - do not allow delete of primary key if it has been imported
+   *         <LI>importedKeyCascade - delete rows that import a deleted key
+   *         <LI>importedKeySetNull - change imported key to NULL if its primary key has been
+   *             deleted
+   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
+   *         <LI>importedKeySetDefault - change imported key to default if its primary key has been
+   *             deleted
+   *       </UL>
+   *   <LI><B>FK_NAME</B> String {@code =>} foreign key name (may be <code>null</code>)
+   *   <LI><B>PK_NAME</B> String {@code =>} primary key name (may be <code>null</code>)
+   *   <LI><B>DEFERRABILITY</B> short {@code =>} can the evaluation of foreign key constraints be
+   *       deferred until commit
+   *       <UL>
+   *         <LI>importedKeyInitiallyDeferred - see SQL92 for definition
+   *         <LI>importedKeyInitiallyImmediate - see SQL92 for definition
+   *         <LI>importedKeyNotDeferrable - see SQL92 for definition
+   *       </UL>
+   * </OL>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schema a schema name; must match the schema name as it is stored in the database; ""
+   *     retrieves those without a schema; <code>null</code> means that the schema name should not
+   *     be used to narrow the search
+   * @param table a table name; must match the table name as it is stored in the database
+   * @return <code>ResultSet</code> - each row is a primary key column description
+   * @throws SQLException if a database access error occurs
+   * @see #getExportedKeys
+   */
+  public ResultSet getImportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+
+    // We avoid using information schema queries by default, because this appears to be an expensive
+    // query (CONJ-41).
+    if (table == null) {
+      throw new SQLException("'table' parameter in getImportedKeys cannot be null");
+    }
+
+    if (catalog == null || catalog.isEmpty()) {
+      return getImportedKeysUsingInformationSchema(catalog, table);
+    }
+
+    try {
+      return getImportedKeysUsingShowCreateTable(catalog, table);
+    } catch (Exception e) {
+      // Likely, parsing failed, try out I_S query.
+      return getImportedKeysUsingInformationSchema(catalog, table);
+    }
+  }
+
+  private String dataTypeClause(String fullTypeColumnName) {
+    return " CASE data_type"
+        + " WHEN 'bit' THEN "
+        + Types.BIT
+        + " WHEN 'tinyblob' THEN "
+        + Types.VARBINARY
+        + " WHEN 'mediumblob' THEN "
+        + Types.LONGVARBINARY
+        + " WHEN 'longblob' THEN "
+        + Types.LONGVARBINARY
+        + " WHEN 'blob' THEN "
+        + Types.LONGVARBINARY
+        + " WHEN 'tinytext' THEN "
+        + Types.VARCHAR
+        + " WHEN 'mediumtext' THEN "
+        + Types.LONGVARCHAR
+        + " WHEN 'longtext' THEN "
+        + Types.LONGVARCHAR
+        + " WHEN 'text' THEN "
+        + Types.LONGVARCHAR
+        + " WHEN 'date' THEN "
+        + Types.DATE
+        + " WHEN 'datetime' THEN "
+        + Types.TIMESTAMP
+        + " WHEN 'decimal' THEN "
+        + Types.DECIMAL
+        + " WHEN 'double' THEN "
+        + Types.DOUBLE
+        + " WHEN 'enum' THEN "
+        + Types.VARCHAR
+        + " WHEN 'float' THEN "
+        + Types.REAL
+        + " WHEN 'int' THEN IF( "
+        + fullTypeColumnName
+        + " like '%unsigned%', "
+        + Types.INTEGER
+        + ","
+        + Types.INTEGER
+        + ")"
+        + " WHEN 'bigint' THEN "
+        + Types.BIGINT
+        + " WHEN 'mediumint' THEN "
+        + Types.INTEGER
+        + " WHEN 'null' THEN "
+        + Types.NULL
+        + " WHEN 'set' THEN "
+        + Types.VARCHAR
+        + " WHEN 'smallint' THEN IF( "
+        + fullTypeColumnName
+        + " like '%unsigned%', "
+        + Types.SMALLINT
+        + ","
+        + Types.SMALLINT
+        + ")"
+        + " WHEN 'varchar' THEN "
+        + Types.VARCHAR
+        + " WHEN 'varbinary' THEN "
+        + Types.VARBINARY
+        + " WHEN 'char' THEN "
+        + Types.CHAR
+        + " WHEN 'binary' THEN "
+        + Types.BINARY
+        + " WHEN 'time' THEN "
+        + Types.TIME
+        + " WHEN 'timestamp' THEN "
+        + Types.TIMESTAMP
+        + " WHEN 'tinyint' THEN "
+        + (conf.tinyInt1isBit()
+            ? "IF("
+                + fullTypeColumnName
+                + " like 'tinyint(1)%',"
+                + (conf.transformedBitIsBoolean() ? Types.BOOLEAN : Types.BIT)
+                + ","
+                + Types.TINYINT
+                + ") "
+            : Types.TINYINT)
+        + " WHEN 'year' THEN "
+        + (conf.yearIsDateType() ? Types.DATE : Types.SMALLINT)
+        + " ELSE "
+        + Types.OTHER
+        + " END ";
+  }
+
+  private ResultSet executeQuery(String sql) throws SQLException {
+    Statement stmt = connection.createStatement();
+    Result rs = (Result) stmt.executeQuery(sql);
+    rs.setStatement(null); // bypass Hibernate statement tracking (CONJ-49)
+    rs.useAliasAsName();
+    return rs;
+  }
+
+  private String escapeQuote(String value) {
+    return value == null
+        ? "null"
+        : "'"
+            + escapeString(
+                value,
+                (connection.getContext().getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) > 0)
+            + "'";
+  }
+
+  /**
+   * Generate part of the information schema query that restricts catalog names In the driver,
+   * catalogs is the equivalent to MariaDB schemas.
+   *
+   * @param columnName - column name in the information schema table
+   * @param catalog - catalog name. This driver does not (always) follow JDBC standard for following
+   *     special values, due to ConnectorJ compatibility 1. empty string ("") - matches current
+   *     catalog (i.e. database). JDBC standard says only tables without catalog should be returned
+   *     - such tables do not exist in MariaDB. If there is no current catalog, then empty string
+   *     matches any catalog. 2. null - if nullCatalogMeansCurrent=true (which is the default), then
+   *     the handling is the same as for "" . i.e. return current catalog.JDBC-conforming way would
+   *     be to match any catalog with null parameter. This can be switched with
+   *     nullCatalogMeansCurrent=false in the connection URL.
+   * @return part of SQL query ,that restricts search for the catalog.
+   */
+  private boolean catalogCond(
+      boolean firstCondition, StringBuilder sb, String columnName, String catalog) {
+    // null catalog => searching without any catalog restriction
+    if (catalog == null) return firstCondition;
+
+    // empty catalog => search restricting to current catalog
+    if (catalog.isEmpty()) {
+      sb.append(firstCondition ? " WHERE " : " AND ").append(columnName).append(" = database()");
+      return false;
+    }
+
+    // search with specified catalog
+    sb.append(firstCondition ? " WHERE " : " AND ")
+        .append(columnName)
+        .append("=")
+        .append(escapeQuote(catalog));
+    return false;
+  }
+
+  // Helper to generate  information schema queries with "like" or "equals" condition (typically  on
+  // table name)
+  private boolean patternCond(
+      boolean firstCondition, StringBuilder sb, String columnName, String tableName) {
+    if (tableName == null || "%".equals(tableName)) {
+      return firstCondition;
+    }
+    sb.append(firstCondition ? " WHERE " : " AND ")
+        .append(columnName)
+        .append((tableName.indexOf('%') == -1 && tableName.indexOf('_') == -1) ? "=" : " LIKE ")
+        .append("'")
+        .append(
+            escapeString(
+                tableName,
+                (connection.getContext().getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES)
+                    != 0))
+        .append("'");
+    return false;
+  }
+
+  /**
+   * Retrieves a description of the given table's primary key columns. They are ordered by
+   * COLUMN_NAME.
+   *
+   * <p>Each primary key column description has the following columns:
+   *
+   * <OL>
+   *   <li><B>TABLE_CAT</B> String {@code =>} table catalog
+   *   <li><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
+   *   <li><B>TABLE_NAME</B> String {@code =>} table name
+   *   <li><B>COLUMN_NAME</B> String {@code =>} column name
+   *   <li><B>KEY_SEQ</B> short {@code =>} sequence number within primary key( a value of 1
+   *       represents the first column of the primary key, a value of 2 would represent the second
+   *       column within the primary key).
+   *   <li><B>PK_NAME</B> String {@code =>} primary key name
+   * </OL>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schema a schema name; must match the schema name as it is stored in the database; ""
+   *     retrieves those without a schema; <code>null</code> means that the schema name should not
+   *     be used to narrow the search
+   * @param table a table name; must match the table name as it is stored in the database
+   * @return <code>ResultSet</code> - each row is a primary key column description
+   * @throws SQLException if a database access error occurs
+   */
+  public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
+    // MySQL 8 now use 'PRI' in place of 'pri'
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT A.TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, A.TABLE_NAME, A.COLUMN_NAME,"
+                + " B.SEQ_IN_INDEX KEY_SEQ, B.INDEX_NAME PK_NAME  FROM INFORMATION_SCHEMA.COLUMNS"
+                + " A, INFORMATION_SCHEMA.STATISTICS B WHERE A.COLUMN_KEY in ('PRI','pri') AND"
+                + " B.INDEX_NAME='PRIMARY'");
+
+    catalogCond(false, sb, "A.TABLE_SCHEMA", catalog);
+    catalogCond(false, sb, "B.TABLE_SCHEMA", catalog);
+    patternCond(false, sb, "A.TABLE_NAME", table);
+    patternCond(false, sb, "B.TABLE_NAME", table);
+    sb.append(
+        " AND A.TABLE_SCHEMA = B.TABLE_SCHEMA AND A.TABLE_NAME = B.TABLE_NAME AND A.COLUMN_NAME ="
+            + " B.COLUMN_NAME ORDER BY A.COLUMN_NAME");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of the tables available in the given catalog. Only table descriptions
+   * matching the catalog, schema, table name and type criteria are returned. They are ordered by
+   * <code>TABLE_TYPE</code>, <code>TABLE_CAT</code>, <code>TABLE_SCHEM</code> and <code>TABLE_NAME
+   * </code>. Each table description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
+   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
+   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
+   *   <LI><B>TABLE_TYPE</B> String {@code =>} table type. Typical types are "TABLE", "VIEW",
+   *       "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+   *   <LI><B>REMARKS</B> String {@code =>} explanatory comment on the table
+   *   <LI><B>TYPE_CAT</B> String {@code =>} the types catalog (may be <code>null</code>)
+   *   <LI><B>TYPE_SCHEM</B> String {@code =>} the types schema (may be <code>null</code>)
+   *   <LI><B>TYPE_NAME</B> String {@code =>} type name (may be <code>null</code>)
+   *   <LI><B>SELF_REFERENCING_COL_NAME</B> String {@code =>} name of the designated "identifier"
+   *       column of a typed table (may be <code>null</code>)
+   *   <LI><B>REF_GENERATION</B> String {@code =>} specifies how values in SELF_REFERENCING_COL_NAME
+   *       are created. Values are "SYSTEM", "USER", "DERIVED". (may be <code>null</code>)
+   * </OL>
+   *
+   * <p><B>Note:</B> Some databases may not return information for all tables.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
+   *     database
+   * @param types a list of table types, which must be from the list of table types returned from
+   *     {@link #getTableTypes},to include; <code>null</code> returns all types
+   * @return <code>ResultSet</code> - each row is a table description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   */
+  public ResultSet getTables(
+      String catalog, String schemaPattern, String tableNamePattern, String[] types)
+      throws SQLException {
+
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT TABLE_SCHEMA TABLE_CAT, NULL  TABLE_SCHEM,  TABLE_NAME, IF(TABLE_TYPE='BASE"
+                + " TABLE' or TABLE_TYPE='SYSTEM VERSIONED', 'TABLE', TABLE_TYPE) as TABLE_TYPE,"
+                + " TABLE_COMMENT REMARKS, NULL TYPE_CAT, NULL TYPE_SCHEM, NULL TYPE_NAME, NULL"
+                + " SELF_REFERENCING_COL_NAME,  NULL REF_GENERATION FROM"
+                + " INFORMATION_SCHEMA.TABLES");
+    boolean firstCondition = true;
+    firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "TABLE_NAME", tableNamePattern);
+
+    if (types != null && types.length > 0) {
+      boolean mustAddType = false;
+
+      StringBuilder sqlType =
+          new StringBuilder(((firstCondition) ? " WHERE " : " AND ") + " TABLE_TYPE IN (");
+      for (String s : types) {
+        if (mustAddType) sqlType.append(",");
+        mustAddType = true;
+        if (s == null) {
+          mustAddType = false;
+          continue;
+        }
+        String type = "TABLE".equals(s) ? "'BASE TABLE','SYSTEM VERSIONED'" : escapeQuote(s);
+        sqlType.append(type);
+      }
+      sqlType.append(")");
+      if (mustAddType) sb.append(sqlType);
+    }
+
+    sb.append(" ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of table columns available in the specified catalog.
+   *
+   * <p>Only column descriptions matching the catalog, schema, table and column name criteria are
+   * returned. They are ordered by <code>TABLE_CAT</code>,<code>TABLE_SCHEM</code>, <code>TABLE_NAME
+   * </code>, and <code>ORDINAL_POSITION</code>.
+   *
+   * <p>Each column description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
+   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
+   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
+   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
+   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
+   *   <LI><B>TYPE_NAME</B> String {@code =>} Data source dependent type name, for a UDT the type
+   *       name is fully qualified
+   *   <LI><B>COLUMN_SIZE</B> int {@code =>} column size.
+   *   <LI><B>BUFFER_LENGTH</B> is not used.
+   *   <LI><B>DECIMAL_DIGITS</B> int {@code =>} the number of fractional digits. Null is returned
+   *       for data types where DECIMAL_DIGITS is not applicable.
+   *   <LI><B>NUM_PREC_RADIX</B> int {@code =>} Radix (typically either 10 or 2)
+   *   <LI><B>NULLABLE</B> int {@code =>} is NULL allowed.
+   *       <UL>
+   *         <LI>columnNoNulls - might not allow <code>NULL</code> values
+   *         <LI>columnNullable - definitely allows <code>NULL</code> values
+   *         <LI>columnNullableUnknown - nullability unknown
+   *       </UL>
+   *   <LI><B>REMARKS</B> String {@code =>} comment describing column (may be <code>null</code>)
+   *   <LI><B>COLUMN_DEF</B> String {@code =>} default value for the column, which should be
+   *       interpreted as a string when the value is enclosed in single quotes (may be <code>null
+   *       </code>)
+   *   <LI><B>SQL_DATA_TYPE</B> int {@code =>} unused
+   *   <LI><B>SQL_DATETIME_SUB</B> int {@code =>} unused
+   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} for char types the maximum number of bytes in the
+   *       column
+   *   <LI><B>ORDINAL_POSITION</B> int {@code =>} index of column in table (starting at 1)
+   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
+   *       a column.
+   *       <UL>
+   *         <LI>YES --- if the column can include NULLs
+   *         <LI>NO --- if the column cannot include NULLs
+   *         <LI>empty string --- if the nullability for the column is unknown
+   *       </UL>
+   *   <LI><B>SCOPE_CATALOG</B> String {@code =>} catalog of table that is the scope of a reference
+   *       attribute (<code>null</code> if DATA_TYPE isn't REF)
+   *   <LI><B>SCOPE_SCHEMA</B> String {@code =>} schema of table that is the scope of a reference
+   *       attribute (<code>null</code> if the DATA_TYPE isn't REF)
+   *   <LI><B>SCOPE_TABLE</B> String {@code =>} table name that this the scope of a reference
+   *       attribute (<code>null</code> if the DATA_TYPE isn't REF)
+   *   <LI><B>SOURCE_DATA_TYPE</B> short {@code =>} source type of a distinct type or user-generated
+   *       Ref type, SQL type from java.sql.Types (<code>null</code> if DATA_TYPE isn't DISTINCT or
+   *       user-generated REF)
+   *   <LI><B>IS_AUTOINCREMENT</B> String {@code =>} Indicates whether this column is auto
+   *       incremented
+   *       <UL>
+   *         <LI>YES --- if the column is auto incremented
+   *         <LI>NO --- if the column is not auto incremented
+   *         <LI>empty string --- if it cannot be determined whether the column is auto incremented
+   *       </UL>
+   *   <LI><B>IS_GENERATEDCOLUMN</B> String {@code =>} Indicates whether this is a generated column
+   *       <UL>
+   *         <LI>YES --- if this a generated column
+   *         <LI>NO --- if this not a generated column
+   *         <LI>empty string --- if it cannot be determined whether this is a generated column
+   *       </UL>
+   * </OL>
+   *
+   * <p>The COLUMN_SIZE column specifies the column size for the given column. For numeric data,
+   * this is the maximum precision. For character data, this is the length in characters. For
+   * datetime datatypes, this is the length in characters of the String representation (assuming the
+   * maximum allowed precision of the fractional seconds component). For binary data, this is the
+   * length in bytes. For the ROWID datatype, this is the length in bytes. Null is returned for data
+   * types where the column size is not applicable.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
+   *     database
+   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
+   *     the database
+   * @return <code>ResultSet</code> - each row is a column description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   */
+  public ResultSet getColumns(
+      String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
+      throws SQLException {
+
+    ServerVersion version = connection.getContext().getVersion();
+    boolean supportsFractionalSeconds =
+        version.isMariaDBServer()
+            /* "In MariaDB 5.3 and later, the TIME, DATETIME, and TIMESTAMP types, along with the temporal
+            functions, CAST and dynamic columns, now support microseconds."
+            https://web.archive.org/web/20130928042640/https://mariadb.com/kb/en/microseconds-in-mariadb/
+            */
+            ? version.versionGreaterOrEqual(5, 3, 0)
+            // See https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-4.html
+            : version.versionGreaterOrEqual(5, 6, 4);
+    StringBuilder sb = new StringBuilder();
+    sb.append(
+        "SELECT TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, TABLE_NAME, COLUMN_NAME,"
+            + dataTypeClause("COLUMN_TYPE")
+            + " DATA_TYPE,"
+            + DataTypeClause(conf)
+            + " TYPE_NAME, "
+            + " CASE DATA_TYPE"
+            + "  WHEN 'date' THEN 10");
+    if (supportsFractionalSeconds) {
+      sb.append(
+          "  WHEN 'time' THEN "
+              + "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
+              + "  WHEN 'datetime' THEN "
+              + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
+              + "  WHEN 'timestamp' THEN "
+              + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))");
+    } else {
+      // Older versions do not include the DATETIME_PRECISION column in INFORMATION_SCHEMA.COLUMNS.
+      sb.append(" WHEN 'time' THEN 10 WHEN 'datetime' THEN 19 WHEN 'timestamp' THEN 19");
+    }
+    sb.append(
+        (conf.yearIsDateType() ? "" : " WHEN 'year' THEN 5")
+            + "  ELSE "
+            + "  IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
+            + Integer.MAX_VALUE
+            + "), NUMERIC_PRECISION) "
+            + " END"
+            + " COLUMN_SIZE, 65535 BUFFER_LENGTH, "
+            + " CONVERT (CASE DATA_TYPE"
+            + " WHEN 'year' THEN "
+            + (conf.yearIsDateType() ? "NUMERIC_SCALE" : "0")
+            + " WHEN 'tinyint' THEN "
+            + (conf.tinyInt1isBit() ? "0" : "NUMERIC_SCALE")
+            + " ELSE NUMERIC_SCALE END, UNSIGNED INTEGER) DECIMAL_DIGITS,"
+            + " 10 NUM_PREC_RADIX, IF(IS_NULLABLE = 'yes',1,0) NULLABLE,COLUMN_COMMENT REMARKS,"
+            + " COLUMN_DEFAULT COLUMN_DEF, 0 SQL_DATA_TYPE, 0 SQL_DATETIME_SUB,  "
+            + " LEAST(CHARACTER_OCTET_LENGTH,"
+            + Integer.MAX_VALUE
+            + ") CHAR_OCTET_LENGTH, ORDINAL_POSITION, IS_NULLABLE, NULL SCOPE_CATALOG, NULL"
+            + " SCOPE_SCHEMA, NULL SCOPE_TABLE, NULL SOURCE_DATA_TYPE, IF(EXTRA ="
+            + " 'auto_increment','YES','NO') IS_AUTOINCREMENT,  IF(EXTRA in ('VIRTUAL',"
+            + " 'PERSISTENT', 'VIRTUAL GENERATED', 'STORED GENERATED') ,'YES','NO')"
+            + " IS_GENERATEDCOLUMN  FROM INFORMATION_SCHEMA.COLUMNS");
+    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "TABLE_NAME", tableNamePattern);
+    firstCondition = patternCond(firstCondition, sb, "COLUMN_NAME", columnNamePattern);
+    sb.append(" ORDER BY TABLE_CAT, TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION");
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of the foreign key columns that reference the given table's primary key
+   * columns (the foreign keys exported by a table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
+   * FKTABLE_NAME, and KEY_SEQ.
+   *
+   * <p>Each foreign key column description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>PKTABLE_CAT</B> String {@code =>} primary key table catalog (may be <code>null</code>)
+   *   <LI><B>PKTABLE_SCHEM</B> String {@code =>} primary key table schema (may be <code>null</code>
+   *       )
+   *   <LI><B>PKTABLE_NAME</B> String {@code =>} primary key table name
+   *   <LI><B>PKCOLUMN_NAME</B> String {@code =>} primary key column name
+   *   <LI><B>FKTABLE_CAT</B> String {@code =>} foreign key table catalog (may be <code>null</code>)
+   *       being exported (may be <code>null</code>)
+   *   <LI><B>FKTABLE_SCHEM</B> String {@code =>} foreign key table schema (may be <code>null</code>
+   *       ) being exported (may be <code>null</code>)
+   *   <LI><B>FKTABLE_NAME</B> String {@code =>} foreign key table name being exported
+   *   <LI><B>FKCOLUMN_NAME</B> String {@code =>} foreign key column name being exported
+   *   <LI><B>KEY_SEQ</B> short {@code =>} sequence number within foreign key( a value of 1
+   *       represents the first column of the foreign key, a value of 2 would represent the second
+   *       column within the foreign key).
+   *   <LI><B>UPDATE_RULE</B> short {@code =>} What happens to foreign key when primary is updated:
+   *       <UL>
+   *         <LI>importedNoAction - do not allow update of primary key if it has been imported
+   *         <LI>importedKeyCascade - change imported key to agree with primary key update
+   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
+   *             has been updated
+   *         <LI>importedKeySetDefault - change imported key to default values if its primary key
+   *             has been updated
+   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
+   *       </UL>
+   *   <LI><B>DELETE_RULE</B> short {@code =>} What happens to the foreign key when primary is
+   *       deleted.
+   *       <UL>
+   *         <LI>importedKeyNoAction - do not allow delete of primary key if it has been imported
+   *         <LI>importedKeyCascade - delete rows that import a deleted key
+   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
+   *             has been deleted
+   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
+   *         <LI>importedKeySetDefault - change imported key to default if its primary key has been
+   *             deleted
+   *       </UL>
+   *   <LI><B>FK_NAME</B> String {@code =>} foreign key name (may be <code>null</code>)
+   *   <LI><B>PK_NAME</B> String {@code =>} primary key name (may be <code>null</code>)
+   *   <LI><B>DEFERRABILITY</B> short {@code =>} can the evaluation of foreign key constraints be
+   *       deferred until commit
+   *       <UL>
+   *         <LI>importedKeyInitiallyDeferred - see SQL92 for definition
+   *         <LI>importedKeyInitiallyImmediate - see SQL92 for definition
+   *         <LI>importedKeyNotDeferrable - see SQL92 for definition
+   *       </UL>
+   * </OL>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in this database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schema a schema name; must match the schema name as it is stored in the database; ""
+   *     retrieves those without a schema; <code>null</code> means that the schema name should not
+   *     be used to narrow the search
+   * @param table a table name; must match the table name as it is stored in this database
+   * @return a <code>ResultSet</code> object in which each row is a foreign key column description
+   * @throws SQLException if a database access error occurs
+   * @see #getImportedKeys
+   */
+  public ResultSet getExportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT KCU.REFERENCED_TABLE_SCHEMA PKTABLE_CAT, NULL PKTABLE_SCHEM, "
+                + " KCU.REFERENCED_TABLE_NAME PKTABLE_NAME, KCU.REFERENCED_COLUMN_NAME"
+                + " PKCOLUMN_NAME, KCU.TABLE_SCHEMA FKTABLE_CAT, NULL FKTABLE_SCHEM, "
+                + " KCU.TABLE_NAME FKTABLE_NAME, KCU.COLUMN_NAME FKCOLUMN_NAME,"
+                + " KCU.POSITION_IN_UNIQUE_CONSTRAINT KEY_SEQ, CASE update_rule    WHEN 'RESTRICT'"
+                + " THEN 1   WHEN 'NO ACTION' THEN 3   WHEN 'CASCADE' THEN 0   WHEN 'SET NULL' THEN"
+                + " 2   WHEN 'SET DEFAULT' THEN 4 END UPDATE_RULE, CASE DELETE_RULE  WHEN"
+                + " 'RESTRICT' THEN 1  WHEN 'NO ACTION' THEN 3  WHEN 'CASCADE' THEN 0  WHEN 'SET"
+                + " NULL' THEN 2  WHEN 'SET DEFAULT' THEN 4 END DELETE_RULE, RC.CONSTRAINT_NAME"
+                + " FK_NAME, RC.UNIQUE_CONSTRAINT_NAME PK_NAME,"
+                + importedKeyNotDeferrable
+                + " DEFERRABILITY"
+                + " FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU"
+                + " INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC"
+                + " ON KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA"
+                + " AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME");
+    boolean firstCondition = true;
+    firstCondition = catalogCond(firstCondition, sb, "KCU.REFERENCED_TABLE_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "KCU.REFERENCED_TABLE_NAME", table);
+    sb.append(" ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, KEY_SEQ");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * GetImportedKeysUsingInformationSchema.
+   *
+   * @param catalog catalog
+   * @param table table
+   * @return resultset
+   * @throws SQLException exception
+   */
+  public ResultSet getImportedKeysUsingInformationSchema(final String catalog, String table)
+      throws SQLException {
+    if (table == null) {
+      throw new SQLException("'table' parameter in getImportedKeys cannot be null");
+    }
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT KCU.REFERENCED_TABLE_SCHEMA PKTABLE_CAT, NULL PKTABLE_SCHEM, "
+                + " KCU.REFERENCED_TABLE_NAME PKTABLE_NAME, KCU.REFERENCED_COLUMN_NAME"
+                + " PKCOLUMN_NAME, KCU.TABLE_SCHEMA FKTABLE_CAT, NULL FKTABLE_SCHEM, "
+                + " KCU.TABLE_NAME FKTABLE_NAME, KCU.COLUMN_NAME FKCOLUMN_NAME,"
+                + " KCU.POSITION_IN_UNIQUE_CONSTRAINT KEY_SEQ, CASE update_rule    WHEN 'RESTRICT'"
+                + " THEN 1   WHEN 'NO ACTION' THEN 3   WHEN 'CASCADE' THEN 0   WHEN 'SET NULL' THEN"
+                + " 2   WHEN 'SET DEFAULT' THEN 4 END UPDATE_RULE, CASE DELETE_RULE  WHEN"
+                + " 'RESTRICT' THEN 1  WHEN 'NO ACTION' THEN 3  WHEN 'CASCADE' THEN 0  WHEN 'SET"
+                + " NULL' THEN 2  WHEN 'SET DEFAULT' THEN 4 END DELETE_RULE, RC.CONSTRAINT_NAME"
+                + " FK_NAME, RC.UNIQUE_CONSTRAINT_NAME PK_NAME,"
+                + importedKeyNotDeferrable
+                + " DEFERRABILITY"
+                + " FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU"
+                + " INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC"
+                + " ON KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA"
+                + " AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME ");
+
+    boolean firstCondition = catalogCond(true, sb, "KCU.TABLE_SCHEMA", catalog);
+    sb.append(firstCondition ? " WHERE " : " AND ")
+        .append("KCU.TABLE_NAME = ")
+        .append(escapeQuote(table));
+
+    sb.append(" ORDER BY PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, KEY_SEQ");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * GetImportedKeysUsingShowCreateTable.
+   *
+   * @param catalog catalog
+   * @param table table
+   * @return resultset
+   * @throws Exception exception
+   */
+  public ResultSet getImportedKeysUsingShowCreateTable(final String catalog, String table)
+      throws Exception {
+    ResultSet rs =
+        connection
+            .createStatement()
+            .executeQuery(
+                "SHOW CREATE TABLE " + quoteIdentifier(catalog) + "." + quoteIdentifier(table));
+    rs.next();
+    String tableDef = rs.getString(2);
+    return getImportedKeys(tableDef, table, catalog, connection);
+  }
+
+  /**
+   * Retrieves a description of a table's optimal set of columns that uniquely identifies a row.
+   * They are ordered by SCOPE.
+   *
+   * <p>Each column description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>SCOPE</B> short {@code =>} actual scope of result
+   *       <UL>
+   *         <LI>bestRowTemporary - very temporary, while using row
+   *         <LI>bestRowTransaction - valid for remainder of current transaction
+   *         <LI>bestRowSession - valid for remainder of current session
+   *       </UL>
+   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
+   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL data type from java.sql.Types
+   *   <LI><B>TYPE_NAME</B> String {@code =>} Data source dependent type name, for a UDT the type
+   *       name is fully qualified
+   *   <LI><B>COLUMN_SIZE</B> int {@code =>} precision
+   *   <LI><B>BUFFER_LENGTH</B> int {@code =>} not used
+   *   <LI><B>DECIMAL_DIGITS</B> short {@code =>} scale - Null is returned for data types where
+   *       DECIMAL_DIGITS is not applicable.
+   *   <LI><B>PSEUDO_COLUMN</B> short {@code =>} is this a pseudo column like an Oracle ROWID
+   *       <UL>
+   *         <LI>bestRowUnknown - may or may not be pseudo column
+   *         <LI>bestRowNotPseudo - is NOT a pseudo column
+   *         <LI>bestRowPseudo - is a pseudo column
+   *       </UL>
+   * </OL>
+   *
+   * <p>The COLUMN_SIZE column represents the specified column size for the given column. For
+   * numeric data, this is the maximum precision. For character data, this is the length in
+   * characters. For datetime datatypes, this is the length in characters of the String
+   * representation (assuming the maximum allowed precision of the fractional seconds component).
+   * For binary data, this is the length in bytes. For the ROWID datatype, this is the length in
+   * bytes. Null is returned for data types where the column size is not applicable.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schema a schema name; must match the schema name as it is stored in the database; ""
+   *     retrieves those without a schema; <code>null</code> means that the schema name should not
+   *     be used to narrow the search
+   * @param table a table name; must match the table name as it is stored in the database
+   * @param scope the scope of interest; use same values as SCOPE
+   * @param nullable include columns that are nullable.
+   * @return <code>ResultSet</code> - each row is a column description
+   * @throws SQLException if a database access error occurs
+   */
+  public ResultSet getBestRowIdentifier(
+      String catalog, String schema, String table, int scope, final boolean nullable)
+      throws SQLException {
+
+    if (table == null) {
+      throw new SQLException("'table' parameter cannot be null in getBestRowIdentifier()");
+    }
+    boolean hasIsGeneratedCol =
+        (connection.getContext().getVersion().isMariaDBServer()
+            && connection.getContext().getVersion().versionGreaterOrEqual(10, 2, 0));
+
+    StringBuilder sbInner =
+        new StringBuilder("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_KEY = 'PRI'");
+    catalogCond(false, sbInner, "TABLE_SCHEMA", catalog);
+    sbInner.append(" AND TABLE_NAME = ").append(escapeQuote(table));
+
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT "
+                + bestRowSession
+                + " SCOPE, COLUMN_NAME,"
+                + dataTypeClause("COLUMN_TYPE")
+                + " DATA_TYPE, DATA_TYPE TYPE_NAME, IF(NUMERIC_PRECISION IS NULL,"
+                + " CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION) COLUMN_SIZE, 0 BUFFER_LENGTH,"
+                + " NUMERIC_SCALE DECIMAL_DIGITS,"
+                + (hasIsGeneratedCol
+                    ? ("IF(IS_GENERATED='NEVER'," + bestRowNotPseudo + "," + bestRowPseudo + ")")
+                    : bestRowNotPseudo)
+                + " PSEUDO_COLUMN"
+                + " FROM INFORMATION_SCHEMA.COLUMNS"
+                + " WHERE (COLUMN_KEY  = 'PRI'"
+                + " OR (COLUMN_KEY = 'UNI' AND NOT EXISTS ("
+                + sbInner
+                + " )))");
+    catalogCond(false, sb, "TABLE_SCHEMA", catalog);
+    sb.append(" AND TABLE_NAME = ").append(escapeQuote(table));
+    if (!nullable) sb.append(" AND IS_NULLABLE = 'NO'");
+
+    return executeQuery(sb.toString());
+  }
+
+  public boolean generatedKeyAlwaysReturned() {
+    return true;
+  }
+
+  /**
+   * Retrieves a description of the pseudo or hidden columns available in a given table within the
+   * specified catalog and schema. Pseudo or hidden columns may not always be stored within a table
+   * and are not visible in a ResultSet unless they are specified in the query's outermost SELECT
+   * list. Pseudo or hidden columns may not necessarily be able to be modified. If there are no
+   * pseudo or hidden columns, an empty ResultSet is returned.
+   *
+   * <p>Only column descriptions matching the catalog, schema, table and column name criteria are
+   * returned. They are ordered by <code>TABLE_CAT</code>,<code>TABLE_SCHEM</code>, <code>TABLE_NAME
+   * </code> and <code>COLUMN_NAME</code>.
+   *
+   * <p>Each column description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
+   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
+   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
+   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
+   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
+   *   <LI><B>COLUMN_SIZE</B> int {@code =>} column size.
+   *   <LI><B>DECIMAL_DIGITS</B> int {@code =>} the number of fractional digits. Null is returned
+   *       for data types where DECIMAL_DIGITS is not applicable.
+   *   <LI><B>NUM_PREC_RADIX</B> int {@code =>} Radix (typically either 10 or 2)
+   *   <LI><B>COLUMN_USAGE</B> String {@code =>} The allowed usage for the column. The value
+   *       returned will correspond to the enum name returned by PseudoColumnUsage.name()
+   *   <LI><B>REMARKS</B> String {@code =>} comment describing column (may be <code>null</code>)
+   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} for char types the maximum number of bytes in the
+   *       column
+   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
+   *       a column.
+   *       <UL>
+   *         <LI>YES --- if the column can include NULLs
+   *         <LI>NO --- if the column cannot include NULLs
+   *         <LI>empty string --- if the nullability for the column is unknown
+   *       </UL>
+   * </OL>
+   *
+   * <p>The COLUMN_SIZE column specifies the column size for the given column. For numeric data,
+   * this is the maximum precision. For character data, this is the length in characters. For
+   * datetime datatypes, this is the length in characters of the String representation (assuming the
+   * maximum allowed precision of the fractional seconds component). For binary data, this is the
+   * length in bytes. For the ROWID datatype, this is the length in bytes. Null is returned for data
+   * types where the column size is not applicable.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
+   *     database
+   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
+   *     the database
+   * @return <code>ResultSet</code> - each row is a column description
+   * @throws SQLException if a database access error occurs
+   * @see PseudoColumnUsage
+   * @since 1.7
+   */
+  public ResultSet getPseudoColumns(
+      String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
+      throws SQLException {
+    return connection
+        .createStatement()
+        .executeQuery(
+            "SELECT ' ' TABLE_CAT, ' ' TABLE_SCHEM, ' ' TABLE_NAME, ' ' COLUMN_NAME, 0 DATA_TYPE, 0"
+                + " COLUMN_SIZE, 0 DECIMAL_DIGITS, 10 NUM_PREC_RADIX, ' ' COLUMN_USAGE,  ' '"
+                + " REMARKS, 0 CHAR_OCTET_LENGTH, 'YES' IS_NULLABLE FROM DUAL WHERE 1=0");
+  }
+
+  public boolean allProceduresAreCallable() {
+    return true;
+  }
+
+  public boolean allTablesAreSelectable() {
+    return true;
+  }
+
+  @Override
+  public String getURL() {
+    return conf.initialUrl();
+  }
+
+  public String getUserName() {
+    return conf.user();
+  }
+
+  public boolean isReadOnly() throws SQLException {
+    java.sql.Statement st = connection.createStatement();
+    ResultSet rs = st.executeQuery("SELECT @@READ_ONLY");
+    rs.next();
+    return rs.getInt(1) == 1;
+  }
+
+  public boolean nullsAreSortedHigh() {
+    return false;
+  }
+
+  public boolean nullsAreSortedLow() {
+    return true;
+  }
+
+  public boolean nullsAreSortedAtStart() {
+    return false;
+  }
+
+  public boolean nullsAreSortedAtEnd() {
+    return true;
+  }
+
+  /**
+   * Return Server type. MySQL or MariaDB. MySQL can be forced for compatibility with option
+   * "useMysqlMetadata"
+   *
+   * @return server type
+   */
+  public String getDatabaseProductName() {
+    if (!conf.useMysqlMetadata() && connection.getContext().getVersion().isMariaDBServer()) {
+      return "MariaDB";
+    }
+    return "MySQL";
+  }
+
+  public String getDatabaseProductVersion() {
+    return connection.getContext().getVersion().getVersion();
+  }
+
+  public String getDriverName() {
+    return DRIVER_NAME;
+  }
+
+  public String getDriverVersion() {
+    return VersionFactory.getInstance().getVersion();
+  }
+
+  public int getDriverMajorVersion() {
+    return VersionFactory.getInstance().getMajorVersion();
+  }
+
+  public int getDriverMinorVersion() {
+    return VersionFactory.getInstance().getMinorVersion();
+  }
+
+  public boolean usesLocalFiles() {
+    return false;
+  }
+
+  public boolean usesLocalFilePerTable() {
+    return false;
+  }
+
+  public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    return (connection.getLowercaseTableNames() == 0);
+  }
+
+  public boolean storesUpperCaseIdentifiers() {
+    return false;
+  }
+
+  public boolean storesLowerCaseIdentifiers() throws SQLException {
+    return (connection.getLowercaseTableNames() == 1);
+  }
+
+  public boolean storesMixedCaseIdentifiers() throws SQLException {
+    return (connection.getLowercaseTableNames() == 2);
+  }
+
+  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    return supportsMixedCaseIdentifiers();
+  }
+
+  public boolean storesUpperCaseQuotedIdentifiers() {
+    return storesUpperCaseIdentifiers();
+  }
+
+  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    return storesLowerCaseIdentifiers();
+  }
+
+  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    return storesMixedCaseIdentifiers();
+  }
+
+  public String getIdentifierQuoteString() {
+    return "`";
+  }
+
+  /**
+   * Retrieves a comma-separated list of all of this database's SQL keywords that are NOT also
+   * SQL:2003 keywords.
+   *
+   * @return the list of this database's keywords that are not also SQL:2003 keywords
+   */
+  @Override
+  public String getSQLKeywords() {
+    return "ACCESSIBLE,ANALYZE,ASENSITIVE,BEFORE,BIGINT,BINARY,BLOB,CALL,CHANGE,CONDITION,DATABASE,DATABASES,"
+               + "DAY_HOUR,DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DELAYED,DETERMINISTIC,DISTINCTROW,DIV,DUAL,EACH,"
+               + "ELSEIF,ENCLOSED,ESCAPED,EXIT,EXPLAIN,FLOAT4,FLOAT8,FORCE,FULLTEXT,GENERAL,HIGH_PRIORITY,"
+               + "HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,IF,IGNORE,IGNORE_SERVER_IDS,INDEX,INFILE,INOUT,INT1,INT2,"
+               + "INT3,INT4,INT8,ITERATE,KEY,KEYS,KILL,LEAVE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,LOCALTIMESTAMP,LOCK,"
+               + "LONG,LONGBLOB,LONGTEXT,LOOP,LOW_PRIORITY,MASTER_HEARTBEAT_PERIOD,MASTER_SSL_VERIFY_SERVER_CERT,"
+               + "MAXVALUE,MEDIUMBLOB,MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,MINUTE_SECOND,MOD,MODIFIES,"
+               + "NO_WRITE_TO_BINLOG,OPTIMIZE,OPTIONALLY,OUT,OUTFILE,PURGE,RANGE,READ_WRITE,READS,REGEXP,RELEASE,"
+               + "RENAME,REPEAT,REPLACE,REQUIRE,RESIGNAL,RESTRICT,RETURN,RLIKE,SCHEMAS,SECOND_MICROSECOND,SENSITIVE,"
+               + "SEPARATOR,SHOW,SIGNAL,SLOW,SPATIAL,SPECIFIC,SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQL_SMALL_RESULT,"
+               + "SQLEXCEPTION,SSL,STARTING,STRAIGHT_JOIN,TERMINATED,TINYBLOB,TINYINT,TINYTEXT,TRIGGER,UNDO,UNLOCK,"
+               + "UNSIGNED,USE,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VARBINARY,VARCHARACTER,WHILE,XOR,YEAR_MONTH,ZEROFILL";
+  }
+
+  /**
+   * List of numeric functions.
+   *
+   * @return List of numeric functions.
+   */
+  @Override
+  public String getNumericFunctions() {
+    return "DIV,ABS,ACOS,ASIN,ATAN,ATAN2,CEIL,CEILING,CONV,COS,COT,CRC32,DEGREES,EXP,FLOOR,GREATEST,LEAST,LN,LOG,"
+               + "LOG10,LOG2,MOD,OCT,PI,POW,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQRT,TAN,TRUNCATE";
+  }
+
+  /**
+   * List of string functions.
+   *
+   * @return List of string functions.
+   */
+  @Override
+  public String getStringFunctions() {
+    return "ASCII,BIN,BIT_LENGTH,CAST,CHARACTER_LENGTH,CHAR_LENGTH,CONCAT,CONCAT_WS,CONVERT,ELT,EXPORT_SET,"
+               + "EXTRACTVALUE,FIELD,FIND_IN_SET,FORMAT,FROM_BASE64,HEX,INSTR,LCASE,LEFT,LENGTH,LIKE,LOAD_FILE,LOCATE,LOWER,LPAD,LTRIM,MAKE_SET,MATCH"
+               + " AGAINST,MID,NOT LIKE,NOT"
+               + " REGEXP,OCTET_LENGTH,ORD,POSITION,QUOTE,REPEAT,REPLACE,REVERSE,RIGHT,RPAD,RTRIM,SOUNDEX,SOUNDS"
+               + " LIKE,SPACE,STRCMP,SUBSTR,SUBSTRING,"
+               + "SUBSTRING_INDEX,TO_BASE64,TRIM,UCASE,UNHEX,UPDATEXML,UPPER,WEIGHT_STRING";
+  }
+
+  /**
+   * List of system functions.
+   *
+   * @return List of system functions.
+   */
+  @Override
+  public String getSystemFunctions() {
+    return "DATABASE,USER,SYSTEM_USER,SESSION_USER,LAST_INSERT_ID,VERSION";
+  }
+
+  /**
+   * List of time and date functions.
+   *
+   * @return List of time and date functions.
+   */
+  @Override
+  public String getTimeDateFunctions() {
+    return "ADDDATE,ADDTIME,CONVERT_TZ,CURDATE,CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURTIME,DATEDIFF,"
+               + "DATE_ADD,DATE_FORMAT,DATE_SUB,DAY,DAYNAME,DAYOFMONTH,DAYOFWEEK,DAYOFYEAR,EXTRACT,FROM_DAYS,"
+               + "FROM_UNIXTIME,GET_FORMAT,HOUR,LAST_DAY,LOCALTIME,LOCALTIMESTAMP,MAKEDATE,MAKETIME,MICROSECOND,"
+               + "MINUTE,MONTH,MONTHNAME,NOW,PERIOD_ADD,PERIOD_DIFF,QUARTER,SECOND,SEC_TO_TIME,STR_TO_DATE,SUBDATE,"
+               + "SUBTIME,SYSDATE,TIMEDIFF,TIMESTAMPADD,TIMESTAMPDIFF,TIME_FORMAT,TIME_TO_SEC,TO_DAYS,TO_SECONDS,"
+               + "UNIX_TIMESTAMP,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,WEEK,WEEKDAY,WEEKOFYEAR,YEAR,YEARWEEK";
+  }
+
+  public String getSearchStringEscape() {
+    return "\\";
+  }
+
+  public String getExtraNameCharacters() {
+    return "#@";
+  }
+
+  public boolean supportsAlterTableWithAddColumn() {
+    return true;
+  }
+
+  public boolean supportsAlterTableWithDropColumn() {
+    return true;
+  }
+
+  public boolean supportsColumnAliasing() {
+    return true;
+  }
+
+  public boolean nullPlusNonNullIsNull() {
+    return true;
+  }
+
+  public boolean supportsConvert() {
+    return true;
+  }
+
+  /**
+   * Retrieves whether this database supports the JDBC scalar function CONVERT for conversions
+   * between the JDBC types fromType and toType. The JDBC types are the generic SQL data types
+   * defined in java.sql.Types.
+   *
+   * @param fromType the type to convert from; one of the type codes from the class java.sql.Types
+   * @param toType the type to convert to; one of the type codes from the class java.sql.Types
+   * @return true if so; false otherwise
+   */
+  public boolean supportsConvert(int fromType, int toType) {
+    switch (fromType) {
+      case Types.TINYINT:
+      case Types.SMALLINT:
+      case Types.INTEGER:
+      case Types.BIGINT:
+      case Types.REAL:
+      case Types.FLOAT:
+      case Types.DECIMAL:
+      case Types.NUMERIC:
+      case Types.DOUBLE:
+      case Types.BIT:
+      case Types.BOOLEAN:
+        switch (toType) {
+          case Types.TINYINT:
+          case Types.SMALLINT:
+          case Types.INTEGER:
+          case Types.BIGINT:
+          case Types.REAL:
+          case Types.FLOAT:
+          case Types.DECIMAL:
+          case Types.NUMERIC:
+          case Types.DOUBLE:
+          case Types.BIT:
+          case Types.BOOLEAN:
+          case Types.CHAR:
+          case Types.VARCHAR:
+          case Types.LONGVARCHAR:
+          case Types.BINARY:
+          case Types.VARBINARY:
+          case Types.LONGVARBINARY:
+            return true;
+          default:
+            return false;
+        }
+
+      case Types.BLOB:
+        switch (toType) {
+          case Types.BINARY:
+          case Types.VARBINARY:
+          case Types.LONGVARBINARY:
+          case Types.CHAR:
+          case Types.VARCHAR:
+          case Types.LONGVARCHAR:
+          case Types.TINYINT:
+          case Types.SMALLINT:
+          case Types.INTEGER:
+          case Types.BIGINT:
+          case Types.REAL:
+          case Types.FLOAT:
+          case Types.DECIMAL:
+          case Types.NUMERIC:
+          case Types.DOUBLE:
+          case Types.BIT:
+          case Types.BOOLEAN:
+            return true;
+          default:
+            return false;
+        }
+
+      case Types.CHAR:
+      case Types.CLOB:
+      case Types.VARCHAR:
+      case Types.LONGVARCHAR:
+      case Types.BINARY:
+      case Types.VARBINARY:
+      case Types.LONGVARBINARY:
+        switch (toType) {
+          case Types.BIT:
+          case Types.TINYINT:
+          case Types.SMALLINT:
+          case Types.INTEGER:
+          case Types.BIGINT:
+          case Types.FLOAT:
+          case Types.REAL:
+          case Types.DOUBLE:
+          case Types.NUMERIC:
+          case Types.DECIMAL:
+          case Types.CHAR:
+          case Types.VARCHAR:
+          case Types.LONGVARCHAR:
+          case Types.BINARY:
+          case Types.VARBINARY:
+          case Types.LONGVARBINARY:
+          case Types.DATE:
+          case Types.TIME:
+          case Types.TIMESTAMP:
+          case Types.BLOB:
+          case Types.CLOB:
+          case Types.BOOLEAN:
+          case Types.NCHAR:
+          case Types.LONGNVARCHAR:
+          case Types.NCLOB:
+            return true;
+          default:
+            return false;
+        }
+
+      case Types.DATE:
+        switch (toType) {
+          case Types.DATE:
+          case Types.CHAR:
+          case Types.VARCHAR:
+          case Types.LONGVARCHAR:
+          case Types.BINARY:
+          case Types.VARBINARY:
+          case Types.LONGVARBINARY:
+            return true;
+
+          default:
+            return false;
+        }
+
+      case Types.TIME:
+        switch (toType) {
+          case Types.TIME:
+          case Types.CHAR:
+          case Types.VARCHAR:
+          case Types.LONGVARCHAR:
+          case Types.BINARY:
+          case Types.VARBINARY:
+          case Types.LONGVARBINARY:
+            return true;
+          default:
+            return false;
+        }
+
+      case Types.TIMESTAMP:
+        switch (toType) {
+          case Types.TIMESTAMP:
+          case Types.CHAR:
+          case Types.VARCHAR:
+          case Types.LONGVARCHAR:
+          case Types.BINARY:
+          case Types.VARBINARY:
+          case Types.LONGVARBINARY:
+          case Types.TIME:
+          case Types.DATE:
+            return true;
+          default:
+            return false;
+        }
+      default:
+        return false;
+    }
+  }
+
+  public boolean supportsTableCorrelationNames() {
+    return true;
+  }
+
+  public boolean supportsDifferentTableCorrelationNames() {
+    return true;
+  }
+
+  public boolean supportsExpressionsInOrderBy() {
+    return true;
+  }
+
+  public boolean supportsOrderByUnrelated() {
+    return true;
+  }
+
+  public boolean supportsGroupBy() {
+    return true;
+  }
+
+  public boolean supportsGroupByUnrelated() {
+    return true;
+  }
+
+  public boolean supportsGroupByBeyondSelect() {
+    return true;
+  }
+
+  public boolean supportsLikeEscapeClause() {
+    return true;
+  }
+
+  public boolean supportsMultipleResultSets() {
+    return true;
+  }
+
+  public boolean supportsMultipleTransactions() {
+    return true;
+  }
+
+  public boolean supportsNonNullableColumns() {
+    return true;
+  }
+
+  @Override
+  public boolean supportsMinimumSQLGrammar() {
+    return true;
+  }
+
+  @Override
+  public boolean supportsCoreSQLGrammar() {
+    return true;
+  }
+
+  @Override
+  public boolean supportsExtendedSQLGrammar() {
+    return true;
+  }
+
+  @Override
+  public boolean supportsANSI92EntryLevelSQL() {
+    return true;
+  }
+
+  @Override
+  public boolean supportsANSI92IntermediateSQL() {
+    return true;
+  }
+
+  @Override
+  public boolean supportsANSI92FullSQL() {
+    return true;
+  }
+
+  public boolean supportsIntegrityEnhancementFacility() {
+    return true;
+  }
+
+  public boolean supportsOuterJoins() {
+    return true;
+  }
+
+  public boolean supportsFullOuterJoins() {
+    return true;
+  }
+
+  public boolean supportsLimitedOuterJoins() {
+    return true;
+  }
+
+  public String getSchemaTerm() {
+    return "schema";
+  }
+
+  public String getProcedureTerm() {
+    return "procedure";
+  }
+
+  public String getCatalogTerm() {
+    return "database";
+  }
+
+  public boolean isCatalogAtStart() {
+    return true;
+  }
+
+  public String getCatalogSeparator() {
+    return ".";
+  }
+
+  public boolean supportsSchemasInDataManipulation() {
+    return false;
+  }
+
+  public boolean supportsSchemasInProcedureCalls() {
+    return false;
+  }
+
+  public boolean supportsSchemasInTableDefinitions() {
+    return false;
+  }
+
+  public boolean supportsSchemasInIndexDefinitions() {
+    return false;
+  }
+
+  public boolean supportsSchemasInPrivilegeDefinitions() {
+    return false;
+  }
+
+  public boolean supportsCatalogsInDataManipulation() {
+    return true;
+  }
+
+  public boolean supportsCatalogsInProcedureCalls() {
+    return true;
+  }
+
+  public boolean supportsCatalogsInTableDefinitions() {
+    return true;
+  }
+
+  public boolean supportsCatalogsInIndexDefinitions() {
+    return true;
+  }
+
+  public boolean supportsCatalogsInPrivilegeDefinitions() {
+    return true;
+  }
+
+  public boolean supportsPositionedDelete() {
+    return false;
+  }
+
+  public boolean supportsPositionedUpdate() {
+    return false;
+  }
+
+  public boolean supportsSelectForUpdate() {
+    return true;
+  }
+
+  public boolean supportsStoredProcedures() {
+    return true;
+  }
+
+  public boolean supportsSubqueriesInComparisons() {
+    return true;
+  }
+
+  public boolean supportsSubqueriesInExists() {
+    return true;
+  }
+
+  public boolean supportsSubqueriesInIns() {
+    return true;
+  }
+
+  public boolean supportsSubqueriesInQuantifieds() {
+    return true;
+  }
+
+  public boolean supportsCorrelatedSubqueries() {
+    return true;
+  }
+
+  public boolean supportsUnion() {
+    return true;
+  }
+
+  public boolean supportsUnionAll() {
+    return true;
+  }
+
+  public boolean supportsOpenCursorsAcrossCommit() {
+    return true;
+  }
+
+  public boolean supportsOpenCursorsAcrossRollback() {
+    return true;
+  }
+
+  public boolean supportsOpenStatementsAcrossCommit() {
+    return true;
+  }
+
+  public boolean supportsOpenStatementsAcrossRollback() {
+    return true;
+  }
+
+  public int getMaxBinaryLiteralLength() {
+    return Integer.MAX_VALUE;
+  }
+
+  public int getMaxCharLiteralLength() {
+    return Integer.MAX_VALUE;
+  }
+
+  public int getMaxColumnNameLength() {
+    return 64;
+  }
+
+  public int getMaxColumnsInGroupBy() {
+    return 64;
+  }
+
+  public int getMaxColumnsInIndex() {
+    return 16;
+  }
+
+  public int getMaxColumnsInOrderBy() {
+    return 64;
+  }
+
+  public int getMaxColumnsInSelect() {
+    return Short.MAX_VALUE;
+  }
+
+  public int getMaxColumnsInTable() {
+    return 0;
+  }
+
+  public int getMaxConnections() {
+    return 0;
+  }
+
+  public int getMaxCursorNameLength() {
+    return 0;
+  }
+
+  public int getMaxIndexLength() {
+    return 256;
+  }
+
+  public int getMaxSchemaNameLength() {
+    return 0;
+  }
+
+  public int getMaxProcedureNameLength() {
+    return 64;
+  }
+
+  public int getMaxCatalogNameLength() {
+    return 0;
+  }
+
+  public int getMaxRowSize() {
+    return 0;
+  }
+
+  public boolean doesMaxRowSizeIncludeBlobs() {
+    return false;
+  }
+
+  public int getMaxStatementLength() {
+    return 0;
+  }
+
+  public int getMaxStatements() {
+    return 0;
+  }
+
+  public int getMaxTableNameLength() {
+    return 64;
+  }
+
+  public int getMaxTablesInSelect() {
+    return 256;
+  }
+
+  public int getMaxUserNameLength() {
+    return 0;
+  }
+
+  public int getDefaultTransactionIsolation() {
+    return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
+  }
+
+  /**
+   * Retrieves whether this database supports transactions. If not, invoking the method <code>commit
+   * </code> is a noop, and the isolation level is <code>TRANSACTION_NONE</code>.
+   *
+   * @return <code>true</code> if transactions are supported; <code>false</code> otherwise
+   */
+  public boolean supportsTransactions() {
+    return true;
+  }
+
+  /* Helper to generate  information schema with "equality" condition (typically on catalog name)
+   */
+
+  /**
+   * Retrieves whether this database supports the given transaction isolation level.
+   *
+   * @param level one of the transaction isolation levels defined in <code>java.sql.Connection
+   *     </code>
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @see java.sql.Connection
+   */
+  public boolean supportsTransactionIsolationLevel(int level) {
+    switch (level) {
+      case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
+      case java.sql.Connection.TRANSACTION_READ_COMMITTED:
+      case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
+      case java.sql.Connection.TRANSACTION_SERIALIZABLE:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  public boolean supportsDataDefinitionAndDataManipulationTransactions() {
+    return true;
+  }
+
+  public boolean supportsDataManipulationTransactionsOnly() {
+    return false;
+  }
+
+  public boolean dataDefinitionCausesTransactionCommit() {
+    return true;
+  }
+
+  public boolean dataDefinitionIgnoredInTransactions() {
+    return false;
+  }
+
+  /**
+   * Retrieves a description of the stored procedures available in the given catalog. Only procedure
+   * descriptions matching the schema and procedure name criteria are returned. They are ordered by
+   * <code>PROCEDURE_CAT</code>, <code>PROCEDURE_SCHEM</code>, <code>PROCEDURE_NAME</code> and
+   * <code>SPECIFIC_ NAME</code>.
+   *
+   * <p>Each procedure description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>PROCEDURE_CAT</B> String {@code =>} procedure catalog (may be <code>null</code>)
+   *   <LI><B>PROCEDURE_SCHEM</B> String {@code =>} procedure schema (may be <code>null</code>)
+   *   <LI><B>PROCEDURE_NAME</B> String {@code =>} procedure name
+   *   <LI>reserved for future use
+   *   <LI>reserved for future use
+   *   <LI>reserved for future use
+   *   <LI><B>REMARKS</B> String {@code =>} explanatory comment on the procedure
+   *   <LI><B>PROCEDURE_TYPE</B> short {@code =>} kind of procedure:
+   *       <UL>
+   *         <LI>procedureResultUnknown - Cannot determine if a return value will be returned
+   *         <LI>procedureNoResult - Does not return a return value
+   *         <LI>procedureReturnsResult - Returns a return value
+   *       </UL>
+   *   <LI><B>SPECIFIC_NAME</B> String {@code =>} The name which uniquely identifies this procedure
+   *       within its schema.
+   * </OL>
+   *
+   * <p>A user may not have permissions to execute any of the procedures that are returned by <code>
+   * getProcedures</code>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param procedureNamePattern a procedure name pattern; must match the procedure name as it is
+   *     stored in the database
+   * @return <code>ResultSet</code> - each row is a procedure description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   */
+  public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
+      throws SQLException {
+
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT ROUTINE_SCHEMA PROCEDURE_CAT,"
+                + "NULL PROCEDURE_SCHEM, "
+                + "ROUTINE_NAME PROCEDURE_NAME,"
+                + " NULL RESERVED1,"
+                + " NULL RESERVED2,"
+                + " NULL RESERVED3,"
+                + " ROUTINE_COMMENT REMARKS,"
+                + " CASE ROUTINE_TYPE "
+                + "  WHEN 'FUNCTION' THEN "
+                + procedureReturnsResult
+                + "  WHEN 'PROCEDURE' THEN "
+                + procedureNoResult
+                + "  ELSE "
+                + procedureResultUnknown
+                + " END PROCEDURE_TYPE,"
+                + " SPECIFIC_NAME "
+                + " FROM INFORMATION_SCHEMA.ROUTINES ");
+
+    boolean firstCondition = catalogCond(true, sb, "ROUTINE_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "ROUTINE_NAME", procedureNamePattern);
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of the given catalog's stored procedure parameter and result columns.
+   *
+   * <p>Only descriptions matching the schema, procedure and parameter name criteria are returned.
+   * They are ordered by PROCEDURE_CAT, PROCEDURE_SCHEM, PROCEDURE_NAME and SPECIFIC_NAME. Within
+   * this, the return value, if any, is first. Next are the parameter descriptions in call order.
+   * The column descriptions follow in column number order.
+   *
+   * <p>Each row in the <code>ResultSet</code> is a parameter description or column description with
+   * the following fields:
+   *
+   * <OL>
+   *   <LI><B>PROCEDURE_CAT</B> String {@code =>} procedure catalog (may be <code>null</code>)
+   *   <LI><B>PROCEDURE_SCHEM</B> String {@code =>} procedure schema (may be <code>null</code>)
+   *   <LI><B>PROCEDURE_NAME</B> String {@code =>} procedure name
+   *   <LI><B>COLUMN_NAME</B> String {@code =>} column/parameter name
+   *   <LI><B>COLUMN_TYPE</B> Short {@code =>} kind of column/parameter:
+   *       <UL>
+   *         <LI>procedureColumnUnknown - nobody knows
+   *         <LI>procedureColumnIn - IN parameter
+   *         <LI>procedureColumnInOut - INOUT parameter
+   *         <LI>procedureColumnOut - OUT parameter
+   *         <LI>procedureColumnReturn - procedure return value
+   *         <LI>procedureColumnResult - result column in <code>ResultSet</code>
+   *       </UL>
+   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
+   *   <LI><B>TYPE_NAME</B> String {@code =>} SQL type name, for a UDT type the type name is fully
+   *       qualified
+   *   <LI><B>PRECISION</B> int {@code =>} precision
+   *   <LI><B>LENGTH</B> int {@code =>} length in bytes of data
+   *   <LI><B>SCALE</B> short {@code =>} scale - null is returned for data types where SCALE is not
+   *       applicable.
+   *   <LI><B>RADIX</B> short {@code =>} radix
+   *   <LI><B>NULLABLE</B> short {@code =>} can it contain NULL.
+   *       <UL>
+   *         <LI>procedureNoNulls - does not allow NULL values
+   *         <LI>procedureNullable - allows NULL values
+   *         <LI>procedureNullableUnknown - nullability unknown
+   *       </UL>
+   *   <LI><B>REMARKS</B> String {@code =>} comment describing parameter/column
+   *   <LI><B>COLUMN_DEF</B> String {@code =>} default value for the column, which should be
+   *       interpreted as a string when the value is enclosed in single quotes (may be <code>null
+   *       </code>)
+   *       <UL>
+   *         <LI>The string NULL (not enclosed in quotes) - if NULL was specified as the default
+   *             value
+   *         <LI>TRUNCATE (not enclosed in quotes) - if the specified default value cannot be
+   *             represented without truncation
+   *         <LI>NULL - if a default value was not specified
+   *       </UL>
+   *   <LI><B>SQL_DATA_TYPE</B> int {@code =>} reserved for future use
+   *   <LI><B>SQL_DATETIME_SUB</B> int {@code =>} reserved for future use
+   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} the maximum length of binary and character based
+   *       columns. For any other datatype the returned value is a NULL
+   *   <LI><B>ORDINAL_POSITION</B> int {@code =>} the ordinal position, starting from 1, for the
+   *       input and output parameters for a procedure. A value of 0 is returned if this row
+   *       describes the procedure's return value. For result set columns, it is the ordinal
+   *       position of the column in the result set starting from 1. If there are multiple result
+   *       sets, the column ordinal positions are implementation defined.
+   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
+   *       a column.
+   *       <UL>
+   *         <LI>YES --- if the column can include NULLs
+   *         <LI>NO --- if the column cannot include NULLs
+   *         <LI>empty string --- if the nullability for the column is unknown
+   *       </UL>
+   *   <LI><B>SPECIFIC_NAME</B> String {@code =>} the name which uniquely identifies this procedure
+   *       within its schema.
+   * </OL>
+   *
+   * <p><B>Note:</B> Some databases may not return the column descriptions for a procedure.
+   *
+   * <p>The PRECISION column represents the specified column size for the given column. For numeric
+   * data, this is the maximum precision. For character data, this is the length in characters. For
+   * datetime datatypes, this is the length in characters of the String representation (assuming the
+   * maximum allowed precision of the fractional seconds component). For binary data, this is the
+   * length in bytes. For the ROWID datatype, this is the length in bytes. Null is returned for data
+   * types where the column size is not applicable.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param procedureNamePattern a procedure name pattern; must match the procedure name as it is
+   *     stored in the database
+   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
+   *     the database
+   * @return <code>ResultSet</code> - each row describes a stored procedure parameter or column
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   */
+  public ResultSet getProcedureColumns(
+      String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern)
+      throws SQLException {
+    /*
+     *  Get info from information_schema.parameters
+     */
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT SPECIFIC_SCHEMA PROCEDURE_CAT, NULL PROCEDURE_SCHEM, SPECIFIC_NAME"
+                + " PROCEDURE_NAME, PARAMETER_NAME COLUMN_NAME,  CASE PARAMETER_MODE   WHEN 'IN'"
+                + " THEN "
+                + procedureColumnIn
+                + "  WHEN 'OUT' THEN "
+                + procedureColumnOut
+                + "  WHEN 'INOUT' THEN "
+                + procedureColumnInOut
+                + "  ELSE IF(PARAMETER_MODE IS NULL,"
+                + procedureColumnReturn
+                + ","
+                + procedureColumnUnknown
+                + ")"
+                + " END COLUMN_TYPE,"
+                + dataTypeClause("DTD_IDENTIFIER")
+                + " DATA_TYPE,"
+                + "DATA_TYPE TYPE_NAME,"
+                + " CASE DATA_TYPE"
+                + "  WHEN 'time' THEN "
+                + "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
+                + "  WHEN 'date' THEN 10"
+                + "  WHEN 'datetime' THEN "
+                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
+                + "  WHEN 'timestamp' THEN "
+                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
+                + "  ELSE "
+                + "  IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
+                + Integer.MAX_VALUE
+                + "), NUMERIC_PRECISION) "
+                + " END `PRECISION`,"
+                + " CASE DATA_TYPE"
+                + "  WHEN 'time' THEN "
+                + "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
+                + "  WHEN 'date' THEN 10"
+                + "  WHEN 'datetime' THEN "
+                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
+                + "  WHEN 'timestamp' THEN "
+                + "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
+                + "  ELSE "
+                + "  IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
+                + Integer.MAX_VALUE
+                + "), NUMERIC_PRECISION) "
+                + " END `LENGTH`,"
+                + " CASE DATA_TYPE"
+                + "  WHEN 'time' THEN CAST(DATETIME_PRECISION as signed integer)"
+                + "  WHEN 'datetime' THEN CAST(DATETIME_PRECISION as signed integer)"
+                + "  WHEN 'timestamp' THEN CAST(DATETIME_PRECISION as signed integer)"
+                + "  ELSE NUMERIC_SCALE "
+                + " END `SCALE`,"
+                + "10 RADIX,"
+                + procedureNullableUnknown
+                + " NULLABLE,NULL REMARKS,NULL COLUMN_DEF,0 SQL_DATA_TYPE,0"
+                + " SQL_DATETIME_SUB,CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH ,ORDINAL_POSITION, ''"
+                + " IS_NULLABLE, SPECIFIC_NAME  FROM INFORMATION_SCHEMA.PARAMETERS");
+
+    boolean firstCondition = catalogCond(true, sb, "SPECIFIC_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "SPECIFIC_NAME", procedureNamePattern);
+    firstCondition = patternCond(firstCondition, sb, "PARAMETER_NAME", columnNamePattern);
+    sb.append(" ORDER BY SPECIFIC_SCHEMA, SPECIFIC_NAME, ORDINAL_POSITION");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of the given catalog's system or user function parameters and return
+   * type.
+   *
+   * <p>Only descriptions matching the schema, function and parameter name criteria are returned.
+   * They are ordered by <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>, <code>FUNCTION_NAME
+   * </code> and <code>SPECIFIC_ NAME</code>. Within this, the return value, if any, is first. Next
+   * are the parameter descriptions in call order. The column descriptions follow in column number
+   * order.
+   *
+   * <p>Each row in the <code>ResultSet</code> is a parameter description, column description or
+   * return type description with the following fields:
+   *
+   * <OL>
+   *   <LI><B>FUNCTION_CAT</B> String {@code =>} function catalog (may be <code>null</code>)
+   *   <LI><B>FUNCTION_SCHEM</B> String {@code =>} function schema (may be <code>null</code>)
+   *   <LI><B>FUNCTION_NAME</B> String {@code =>} function name. This is the name used to invoke the
+   *       function
+   *   <LI><B>COLUMN_NAME</B> String {@code =>} column/parameter name
+   *   <LI><B>COLUMN_TYPE</B> Short {@code =>} kind of column/parameter:
+   *       <UL>
+   *         <LI>functionColumnUnknown - nobody knows
+   *         <LI>functionColumnIn - IN parameter
+   *         <LI>functionColumnInOut - INOUT parameter
+   *         <LI>functionColumnOut - OUT parameter
+   *         <LI>functionColumnReturn - function return value
+   *         <LI>functionColumnResult - Indicates that the parameter or column is a column in the
+   *             <code>ResultSet</code>
+   *       </UL>
+   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL type from java.sql.Types
+   *   <LI><B>TYPE_NAME</B> String {@code =>} SQL type name, for a UDT type the type name is fully
+   *       qualified
+   *   <LI><B>PRECISION</B> int {@code =>} precision
+   *   <LI><B>LENGTH</B> int {@code =>} length in bytes of data
+   *   <LI><B>SCALE</B> short {@code =>} scale - null is returned for data types where SCALE is not
+   *       applicable.
+   *   <LI><B>RADIX</B> short {@code =>} radix
+   *   <LI><B>NULLABLE</B> short {@code =>} can it contain NULL.
+   *       <UL>
+   *         <LI>functionNoNulls - does not allow NULL values
+   *         <LI>functionNullable - allows NULL values
+   *         <LI>functionNullableUnknown - nullability unknown
+   *       </UL>
+   *   <LI><B>REMARKS</B> String {@code =>} comment describing column/parameter
+   *   <LI><B>CHAR_OCTET_LENGTH</B> int {@code =>} the maximum length of binary and character based
+   *       parameters or columns. For any other datatype the returned value is a NULL
+   *   <LI><B>ORDINAL_POSITION</B> int {@code =>} the ordinal position, starting from 1, for the
+   *       input and output parameters. A value of 0 is returned if this row describes the
+   *       function's return value. For result set columns, it is the ordinal position of the column
+   *       in the result set starting from 1.
+   *   <LI><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
+   *       a parameter or column.
+   *       <UL>
+   *         <LI>YES --- if the parameter or column can include NULLs
+   *         <LI>NO --- if the parameter or column cannot include NULLs
+   *         <LI>empty string --- if the nullability for the parameter or column is unknown
+   *       </UL>
+   *   <LI><B>SPECIFIC_NAME</B> String {@code =>} the name which uniquely identifies this function
+   *       within its schema. This is a user specified, or DBMS generated, name that may be
+   *       different then the <code>FUNCTION_NAME</code> for example with overload functions
+   * </OL>
+   *
+   * <p>The PRECISION column represents the specified column size for the given parameter or column.
+   * For numeric data, this is the maximum precision. For character data, this is the length in
+   * characters. For datetime datatypes, this is the length in characters of the String
+   * representation (assuming the maximum allowed precision of the fractional seconds component).
+   * For binary data, this is the length in bytes. For the ROWID datatype, this is the length in
+   * bytes. Null is returned for data types where the column size is not applicable.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param functionNamePattern a procedure name pattern; must match the function name as it is
+   *     stored in the database
+   * @param columnNamePattern a parameter name pattern; must match the parameter or column name as
+   *     it is stored in the database
+   * @return <code>ResultSet</code> - each row describes a user function parameter, column or return
+   *     type
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   * @since 1.6
+   */
+  public ResultSet getFunctionColumns(
+      String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern)
+      throws SQLException {
+
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT SPECIFIC_SCHEMA `FUNCTION_CAT`, NULL `FUNCTION_SCHEM`, SPECIFIC_NAME"
+                + " FUNCTION_NAME, PARAMETER_NAME COLUMN_NAME,  CASE PARAMETER_MODE   WHEN 'IN'"
+                + " THEN "
+                + functionColumnIn
+                + "  WHEN 'OUT' THEN "
+                + functionColumnOut
+                + "  WHEN 'INOUT' THEN "
+                + functionColumnInOut
+                + "  ELSE "
+                + functionReturn
+                + " END COLUMN_TYPE,"
+                + dataTypeClause("DTD_IDENTIFIER")
+                + " DATA_TYPE,DATA_TYPE TYPE_NAME,NUMERIC_PRECISION"
+                + " `PRECISION`,CHARACTER_MAXIMUM_LENGTH LENGTH,NUMERIC_SCALE SCALE,10 RADIX,"
+                + procedureNullableUnknown
+                + " NULLABLE,NULL REMARKS,CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH"
+                + " ,ORDINAL_POSITION, '' IS_NULLABLE, SPECIFIC_NAME  FROM"
+                + " INFORMATION_SCHEMA.PARAMETERS");
+
+    boolean firstCondition = catalogCond(true, sb, "SPECIFIC_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "SPECIFIC_NAME", functionNamePattern);
+    firstCondition = patternCond(firstCondition, sb, "PARAMETER_NAME", columnNamePattern);
+    sb.append(firstCondition ? " WHERE " : " AND ")
+        .append(" ROUTINE_TYPE='FUNCTION' ORDER BY FUNCTION_CAT, SPECIFIC_NAME, ORDINAL_POSITION");
+
+    return executeQuery(sb.toString());
+  }
+
+  public ResultSet getSchemas() throws SQLException {
+    return executeQuery("SELECT '' TABLE_SCHEM, '' TABLE_catalog  FROM DUAL WHERE 1=0");
+  }
+
+  public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
+    return executeQuery("SELECT  ' ' table_schem, ' ' table_catalog FROM DUAL WHERE 1=0");
+  }
+
+  public ResultSet getCatalogs() throws SQLException {
+    return executeQuery("SELECT SCHEMA_NAME TABLE_CAT FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY 1");
+  }
+
+  public ResultSet getTableTypes() throws SQLException {
+    return executeQuery(
+        "SELECT 'TABLE' TABLE_TYPE UNION SELECT 'SYSTEM VIEW' TABLE_TYPE UNION SELECT 'VIEW'"
+            + " TABLE_TYPE");
+  }
+
+  /**
+   * Retrieves a description of the access rights for a table's columns.
+   *
+   * <p>Only privileges matching the column name criteria are returned. They are ordered by
+   * COLUMN_NAME and PRIVILEGE.
+   *
+   * <p>Each privilege description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
+   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
+   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
+   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
+   *   <LI><B>GRANTOR</B> String {@code =>} grantor of access (may be <code>null</code>)
+   *   <LI><B>GRANTEE</B> String {@code =>} grantee of access
+   *   <LI><B>PRIVILEGE</B> String {@code =>} name of access (SELECT, INSERT, UPDATE, REFRENCES,
+   *       ...)
+   *   <LI><B>IS_GRANTABLE</B> String {@code =>} "YES" if grantee is permitted to grant to others;
+   *       "NO" if not; <code>null</code> if unknown
+   * </OL>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schema a schema name; must match the schema name as it is stored in the database; ""
+   *     retrieves those without a schema; <code>null</code> means that the schema name should not
+   *     be used to narrow the search
+   * @param table a table name; must match the table name as it is stored in the database
+   * @param columnNamePattern a column name pattern; must match the column name as it is stored in
+   *     the database
+   * @return <code>ResultSet</code> - each row is a column privilege description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   */
+  public ResultSet getColumnPrivileges(
+      String catalog, String schema, String table, String columnNamePattern) throws SQLException {
+
+    if (table == null) {
+      throw new SQLException("'table' parameter must not be null");
+    }
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT TABLE_SCHEMA TABLE_CAT, "
+                + "NULL TABLE_SCHEM, "
+                + "TABLE_NAME, "
+                + "COLUMN_NAME, "
+                + "NULL AS GRANTOR, "
+                + "GRANTEE, "
+                + "PRIVILEGE_TYPE AS PRIVILEGE, "
+                + "IS_GRANTABLE "
+                + "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES");
+    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
+    sb.append(firstCondition ? " WHERE " : " AND ")
+        .append(" TABLE_NAME = ")
+        .append(escapeQuote(table));
+    patternCond(false, sb, "COLUMN_NAME", columnNamePattern);
+    sb.append(" ORDER BY COLUMN_NAME, PRIVILEGE_TYPE");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of the access rights for each table available in a catalog. Note that a
+   * table privilege applies to one or more columns in the table. It would be wrong to assume that
+   * this privilege applies to all columns (this may be true for some systems but is not true for
+   * all.)
+   *
+   * <p>Only privileges matching the schema and table name criteria are returned. They are ordered
+   * by <code>TABLE_CAT</code>, <code>TABLE_SCHEM</code>, <code>TABLE_NAME</code>, and <code>
+   * PRIVILEGE</code>.
+   *
+   * <p>Each privilege description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
+   *   <LI><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
+   *   <LI><B>TABLE_NAME</B> String {@code =>} table name
+   *   <LI><B>GRANTOR</B> String {@code =>} grantor of access (may be <code>null</code>)
+   *   <LI><B>GRANTEE</B> String {@code =>} grantee of access
+   *   <LI><B>PRIVILEGE</B> String {@code =>} name of access (SELECT, INSERT, UPDATE, REFRENCES,
+   *       ...)
+   *   <LI><B>IS_GRANTABLE</B> String {@code =>} "YES" if grantee is permitted to grant to others;
+   *       "NO" if not; <code>null</code> if unknown
+   * </OL>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param tableNamePattern a table name pattern; must match the table name as it is stored in the
+   *     database
+   * @return <code>ResultSet</code> - each row is a table privilege description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   */
+  public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
+      throws SQLException {
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT TABLE_SCHEMA TABLE_CAT, "
+                + "NULL TABLE_SCHEM, "
+                + "TABLE_NAME, "
+                + "NULL GRANTOR,"
+                + "GRANTEE, "
+                + "PRIVILEGE_TYPE PRIVILEGE, "
+                + "IS_GRANTABLE "
+                + "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES");
+    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "TABLE_NAME", tableNamePattern);
+    sb.append(" ORDER BY TABLE_SCHEMA, TABLE_NAME,  PRIVILEGE_TYPE ");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of a table's columns that are automatically updated when any value in a
+   * row is updated. They are unordered.
+   *
+   * <p>Each column description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>SCOPE</B> short {@code =>} is not used
+   *   <LI><B>COLUMN_NAME</B> String {@code =>} column name
+   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL data type from <code>java.sql.Types</code>
+   *   <LI><B>TYPE_NAME</B> String {@code =>} Data source-dependent type name
+   *   <LI><B>COLUMN_SIZE</B> int {@code =>} precision
+   *   <LI><B>BUFFER_LENGTH</B> int {@code =>} length of column value in bytes
+   *   <LI><B>DECIMAL_DIGITS</B> short {@code =>} scale - Null is returned for data types where
+   *       DECIMAL_DIGITS is not applicable.
+   *   <LI><B>PSEUDO_COLUMN</B> short {@code =>} whether this is pseudo column like an Oracle ROWID
+   *       <UL>
+   *         <LI>versionColumnUnknown - may or may not be pseudo column
+   *         <LI>versionColumnNotPseudo - is NOT a pseudo column
+   *         <LI>versionColumnPseudo - is a pseudo column
+   *       </UL>
+   * </OL>
+   *
+   * <p>The COLUMN_SIZE column represents the specified column size for the given column. For
+   * numeric data, this is the maximum precision. For character data, this is the length in
+   * characters. For datetime datatypes, this is the length in characters of the String
+   * representation (assuming the maximum allowed precision of the fractional seconds component).
+   * For binary data, this is the length in bytes. For the ROWID datatype, this is the length in
+   * bytes. Null is returned for data types where the column size is not applicable.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog;<code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schema a schema name; must match the schema name as it is stored in the database; ""
+   *     retrieves those without a schema; <code>null</code> means that the schema name should not
+   *     be used to narrow the search
+   * @param table a table name; must match the table name as it is stored in the database
+   * @return a <code>ResultSet</code> object in which each row is a column description
+   * @throws SQLException if a database access error occurs
+   */
+  public ResultSet getVersionColumns(String catalog, String schema, String table)
+      throws SQLException {
+    String sql =
+        "SELECT 0 SCOPE, ' ' COLUMN_NAME, 0 DATA_TYPE,"
+            + " ' ' TYPE_NAME, 0 COLUMN_SIZE, 0 BUFFER_LENGTH,"
+            + " 0 DECIMAL_DIGITS, 0 PSEUDO_COLUMN "
+            + " FROM DUAL WHERE 1 = 0";
+    return executeQuery(sql);
+  }
+
+  /**
+   * Retrieves a description of the foreign key columns in the given foreign key table that
+   * reference the primary key or the columns representing a unique constraint of the parent table
+   * (could be the same or a different table). The number of columns returned from the parent table
+   * must match the number of columns that make up the foreign key. They are ordered by FKTABLE_CAT,
+   * FKTABLE_SCHEM, FKTABLE_NAME, and KEY_SEQ.
+   *
+   * <p>Each foreign key column description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>PKTABLE_CAT</B> String {@code =>} parent key table catalog (may be <code>null</code>)
+   *   <LI><B>PKTABLE_SCHEM</B> String {@code =>} parent key table schema (may be <code>null</code>)
+   *   <LI><B>PKTABLE_NAME</B> String {@code =>} parent key table name
+   *   <LI><B>PKCOLUMN_NAME</B> String {@code =>} parent key column name
+   *   <LI><B>FKTABLE_CAT</B> String {@code =>} foreign key table catalog (may be <code>null</code>)
+   *       being exported (may be <code>null</code>)
+   *   <LI><B>FKTABLE_SCHEM</B> String {@code =>} foreign key table schema (may be <code>null</code>
+   *       ) being exported (may be <code>null</code>)
+   *   <LI><B>FKTABLE_NAME</B> String {@code =>} foreign key table name being exported
+   *   <LI><B>FKCOLUMN_NAME</B> String {@code =>} foreign key column name being exported
+   *   <LI><B>KEY_SEQ</B> short {@code =>} sequence number within foreign key( a value of 1
+   *       represents the first column of the foreign key, a value of 2 would represent the second
+   *       column within the foreign key).
+   *   <LI><B>UPDATE_RULE</B> short {@code =>} What happens to foreign key when parent key is
+   *       updated:
+   *       <UL>
+   *         <LI>importedNoAction - do not allow update of parent key if it has been imported
+   *         <LI>importedKeyCascade - change imported key to agree with parent key update
+   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its parent key has
+   *             been updated
+   *         <LI>importedKeySetDefault - change imported key to default values if its parent key has
+   *             been updated
+   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
+   *       </UL>
+   *   <LI><B>DELETE_RULE</B> short {@code =>} What happens to the foreign key when parent key is
+   *       deleted.
+   *       <UL>
+   *         <LI>importedKeyNoAction - do not allow delete of parent key if it has been imported
+   *         <LI>importedKeyCascade - delete rows that import a deleted key
+   *         <LI>importedKeySetNull - change imported key to <code>NULL</code> if its primary key
+   *             has been deleted
+   *         <LI>importedKeyRestrict - same as importedKeyNoAction (for ODBC 2.x compatibility)
+   *         <LI>importedKeySetDefault - change imported key to default if its parent key has been
+   *             deleted
+   *       </UL>
+   *   <LI><B>FK_NAME</B> String {@code =>} foreign key name (may be <code>null</code>)
+   *   <LI><B>PK_NAME</B> String {@code =>} parent key name (may be <code>null</code>)
+   *   <LI><B>DEFERRABILITY</B> short {@code =>} can the evaluation of foreign key constraints be
+   *       deferred until commit
+   *       <UL>
+   *         <LI>importedKeyInitiallyDeferred - see SQL92 for definition
+   *         <LI>importedKeyInitiallyImmediate - see SQL92 for definition
+   *         <LI>importedKeyNotDeferrable - see SQL92 for definition
+   *       </UL>
+   * </OL>
+   *
+   * @param parentCatalog a catalog name; must match the catalog name as it is stored in the
+   *     database; "" retrieves those without a catalog; <code>null</code> means drop catalog name
+   *     from the selection criteria
+   * @param parentSchema a schema name; must match the schema name as it is stored in the database;
+   *     "" retrieves those without a schema; <code>null</code> means drop schema name from the
+   *     selection criteria
+   * @param parentTable the name of the table that exports the key; pattern, or null (means any
+   *     table) value
+   * @param foreignCatalog a catalog name; must match the catalog name as it is stored in the
+   *     database; "" retrieves those without a catalog; <code>null</code> means drop catalog name
+   *     from the selection criteria
+   * @param foreignSchema a schema name; must match the schema name as it is stored in the database;
+   *     "" retrieves those without a schema; <code>null</code> means drop schema name from the
+   *     selection criteria
+   * @param foreignTable the name of the table that imports the key; pattern, or null (means any
+   *     table) value is stored in the database
+   * @return <code>ResultSet</code> - each row is a foreign key column description
+   * @throws SQLException if a database access error occurs
+   * @see #getImportedKeys
+   */
+  public ResultSet getCrossReference(
+      String parentCatalog,
+      String parentSchema,
+      String parentTable,
+      String foreignCatalog,
+      String foreignSchema,
+      String foreignTable)
+      throws SQLException {
+
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT KCU.REFERENCED_TABLE_SCHEMA PKTABLE_CAT, NULL PKTABLE_SCHEM, "
+                + " KCU.REFERENCED_TABLE_NAME PKTABLE_NAME, KCU.REFERENCED_COLUMN_NAME"
+                + " PKCOLUMN_NAME, KCU.TABLE_SCHEMA FKTABLE_CAT, NULL FKTABLE_SCHEM, "
+                + " KCU.TABLE_NAME FKTABLE_NAME, KCU.COLUMN_NAME FKCOLUMN_NAME,"
+                + " KCU.POSITION_IN_UNIQUE_CONSTRAINT KEY_SEQ, CASE update_rule    WHEN 'RESTRICT'"
+                + " THEN 1   WHEN 'NO ACTION' THEN 3   WHEN 'CASCADE' THEN 0   WHEN 'SET NULL' THEN"
+                + " 2   WHEN 'SET DEFAULT' THEN 4 END UPDATE_RULE, CASE DELETE_RULE  WHEN"
+                + " 'RESTRICT' THEN 1  WHEN 'NO ACTION' THEN 3  WHEN 'CASCADE' THEN 0  WHEN 'SET"
+                + " NULL' THEN 2  WHEN 'SET DEFAULT' THEN 4 END DELETE_RULE, RC.CONSTRAINT_NAME"
+                + " FK_NAME, RC.UNIQUE_CONSTRAINT_NAME PK_NAME,"
+                + importedKeyNotDeferrable
+                + " DEFERRABILITY "
+                + "FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU"
+                + " INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC"
+                + " ON KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA"
+                + " AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME ");
+
+    boolean firstCondition = catalogCond(true, sb, "KCU.REFERENCED_TABLE_SCHEMA", parentCatalog);
+    firstCondition = catalogCond(firstCondition, sb, "KCU.TABLE_SCHEMA", foreignCatalog);
+    firstCondition = patternCond(firstCondition, sb, "KCU.REFERENCED_TABLE_NAME", parentTable);
+    firstCondition = patternCond(firstCondition, sb, "KCU.TABLE_NAME", foreignTable);
+    sb.append("ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, KEY_SEQ");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves a description of all the data types supported by this database. They are ordered by
+   * DATA_TYPE and then by how closely the data type maps to the corresponding JDBC SQL type.
+   *
+   * <p>If the database supports SQL distinct types, then getTypeInfo() will return a single row
+   * with a TYPE_NAME of DISTINCT and a DATA_TYPE of Types.DISTINCT. If the database supports SQL
+   * structured types, then getTypeInfo() will return a single row with a TYPE_NAME of STRUCT and a
+   * DATA_TYPE of Types.STRUCT.
+   *
+   * <p>If SQL distinct or structured types are supported, then information on the individual types
+   * may be obtained from the getUDTs() method.
+   *
+   * <p>Each type description has the following columns:
+   *
+   * <OL>
+   *   <LI><B>TYPE_NAME</B> String {@code =>} Type name
+   *   <LI><B>DATA_TYPE</B> int {@code =>} SQL data type from java.sql.Types
+   *   <LI><B>PRECISION</B> int {@code =>} maximum precision
+   *   <LI><B>LITERAL_PREFIX</B> String {@code =>} prefix used to quote a literal (may be <code>null
+   *       </code>)
+   *   <LI><B>LITERAL_SUFFIX</B> String {@code =>} suffix used to quote a literal (may be <code>null
+   *       </code>)
+   *   <LI><B>CREATE_PARAMS</B> String {@code =>} parameters used in creating the type (may be
+   *       <code>null</code>)
+   *   <LI><B>NULLABLE</B> short {@code =>} can you use NULL for this type.
+   *       <UL>
+   *         <LI>typeNoNulls - does not allow NULL values
+   *         <LI>typeNullable - allows NULL values
+   *         <LI>typeNullableUnknown - nullability unknown
+   *       </UL>
+   *   <LI><B>CASE_SENSITIVE</B> boolean{@code =>} is it case sensitive.
+   *   <LI><B>SEARCHABLE</B> short {@code =>} can you use "WHERE" based on this type:
+   *       <UL>
+   *         <LI>typePredNone - No support
+   *         <LI>typePredChar - Only supported with WHERE .. LIKE
+   *         <LI>typePredBasic - Supported except for WHERE .. LIKE
+   *         <LI>typeSearchable - Supported for all WHERE ..
+   *       </UL>
+   *   <LI><B>UNSIGNED_ATTRIBUTE</B> boolean {@code =>} is it unsigned.
+   *   <LI><B>FIXED_PREC_SCALE</B> boolean {@code =>} can it be a money value.
+   *   <LI><B>AUTO_INCREMENT</B> boolean {@code =>} can it be used for an auto-increment value.
+   *   <LI><B>LOCAL_TYPE_NAME</B> String {@code =>} localized version of type name (may be <code>
+   *       null</code>)
+   *   <LI><B>MINIMUM_SCALE</B> short {@code =>} minimum scale supported
+   *   <LI><B>MAXIMUM_SCALE</B> short {@code =>} maximum scale supported
+   *   <LI><B>SQL_DATA_TYPE</B> int {@code =>} unused
+   *   <LI><B>SQL_DATETIME_SUB</B> int {@code =>} unused
+   *   <LI><B>NUM_PREC_RADIX</B> int {@code =>} usually 2 or 10
+   * </OL>
+   *
+   * <p>The PRECISION column represents the maximum column size that the server supports for the
+   * given datatype. For numeric data, this is the maximum precision. For character data, this is
+   * the length in characters. For datetime datatypes, this is the length in characters of the
+   * String representation (assuming the maximum allowed precision of the fractional seconds
+   * component). For binary data, this is the length in bytes. For the ROWID datatype, this is the
+   * length in bytes. Null is returned for data types where the column size is not applicable.
+   *
+   * @return a <code>ResultSet</code> object in which each row is an SQL type description
+   */
+  public ResultSet getTypeInfo() {
+    String[] columnNames = {
+      "TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", "LITERAL_SUFFIX",
+      "CREATE_PARAMS", "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE",
+      "FIXED_PREC_SCALE", "AUTO_INCREMENT", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE",
+      "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX"
+    };
+    DataType[] dataTypes = {
+      DataType.VARCHAR,
+      DataType.INTEGER,
+      DataType.INTEGER,
+      DataType.VARCHAR,
+      DataType.VARCHAR,
+      DataType.VARCHAR,
+      DataType.INTEGER,
+      DataType.BIT,
+      DataType.SMALLINT,
+      DataType.BIT,
+      DataType.BIT,
+      DataType.BIT,
+      DataType.VARCHAR,
+      DataType.SMALLINT,
+      DataType.SMALLINT,
+      DataType.INTEGER,
+      DataType.INTEGER,
+      DataType.INTEGER
+    };
+
+    String[][] data = {
+      {"BIT", "-7", "1", "", "", "", "1", "1", "3", "0", "0", "0", "BIT", "0", "0", "0", "0", "10"},
+      {
+        "BOOL", "-7", "1", "", "", "", "1", "1", "3", "0", "0", "0", "BOOL", "0", "0", "0", "0",
+        "10"
+      },
+      {
+        "TINYINT",
+        "-6",
+        "3",
+        "",
+        "",
+        "[(M)] [UNSIGNED] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "TINYINT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "TINYINT UNSIGNED",
+        "-6",
+        "3",
+        "",
+        "",
+        "[(M)] [UNSIGNED] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "TINYINT UNSIGNED",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "BIGINT",
+        "-5",
+        "19",
+        "",
+        "",
+        "[(M)] [UNSIGNED] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "BIGINT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "BIGINT UNSIGNED",
+        "-5",
+        "20",
+        "",
+        "",
+        "[(M)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "BIGINT UNSIGNED",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "LONG VARBINARY",
+        "-4",
+        "16777215",
+        "'",
+        "'",
+        "",
+        "1",
+        "1",
+        "3",
+        "0",
+        "0",
+        "0",
+        "LONG VARBINARY",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "MEDIUMBLOB",
+        "-4",
+        "16777215",
+        "'",
+        "'",
+        "",
+        "1",
+        "1",
+        "3",
+        "0",
+        "0",
+        "0",
+        "MEDIUMBLOB",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "LONGBLOB",
+        "-4",
+        "2147483647",
+        "'",
+        "'",
+        "",
+        "1",
+        "1",
+        "3",
+        "0",
+        "0",
+        "0",
+        "LONGBLOB",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "BLOB", "-4", "65535", "'", "'", "", "1", "1", "3", "0", "0", "0", "BLOB", "0", "0", "0",
+        "0", "10"
+      },
+      {
+        "TINYBLOB",
+        "-4",
+        "255",
+        "'",
+        "'",
+        "",
+        "1",
+        "1",
+        "3",
+        "0",
+        "0",
+        "0",
+        "TINYBLOB",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "VARBINARY",
+        "-3",
+        "255",
+        "'",
+        "'",
+        "(M)",
+        "1",
+        "1",
+        "3",
+        "0",
+        "0",
+        "0",
+        "VARBINARY",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "BINARY", "-2", "255", "'", "'", "(M)", "1", "1", "3", "0", "0", "0", "BINARY", "0", "0",
+        "0", "0", "10"
+      },
+      {
+        "LONG VARCHAR",
+        "-1",
+        "16777215",
+        "'",
+        "'",
+        "",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "0",
+        "LONG VARCHAR",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "MEDIUMTEXT",
+        "-1",
+        "16777215",
+        "'",
+        "'",
+        "",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "0",
+        "MEDIUMTEXT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "LONGTEXT",
+        "-1",
+        "2147483647",
+        "'",
+        "'",
+        "",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "0",
+        "LONGTEXT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "TEXT", "-1", "65535", "'", "'", "", "1", "0", "3", "0", "0", "0", "TEXT", "0", "0", "0",
+        "0", "10"
+      },
+      {
+        "TINYTEXT",
+        "-1",
+        "255",
+        "'",
+        "'",
+        "",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "0",
+        "TINYTEXT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "CHAR", "1", "255", "'", "'", "(M)", "1", "0", "3", "0", "0", "0", "CHAR", "0", "0", "0",
+        "0", "10"
+      },
+      {
+        "NUMERIC",
+        "2",
+        "65",
+        "",
+        "",
+        "[(M,D])] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "1",
+        "NUMERIC",
+        "-308",
+        "308",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "DECIMAL",
+        "3",
+        "65",
+        "",
+        "",
+        "[(M,D])] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "1",
+        "DECIMAL",
+        "-308",
+        "308",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "INTEGER",
+        "4",
+        "10",
+        "",
+        "",
+        "[(M)] [UNSIGNED] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "INTEGER",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "INTEGER UNSIGNED",
+        "4",
+        "10",
+        "",
+        "",
+        "[(M)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "INTEGER UNSIGNED",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "INT",
+        "4",
+        "10",
+        "",
+        "",
+        "[(M)] [UNSIGNED] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "INT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "INT UNSIGNED",
+        "4",
+        "10",
+        "",
+        "",
+        "[(M)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "INT UNSIGNED",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "MEDIUMINT",
+        "4",
+        "7",
+        "",
+        "",
+        "[(M)] [UNSIGNED] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "MEDIUMINT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "MEDIUMINT UNSIGNED",
+        "4",
+        "8",
+        "",
+        "",
+        "[(M)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "MEDIUMINT UNSIGNED",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "SMALLINT",
+        "5",
+        "5",
+        "",
+        "",
+        "[(M)] [UNSIGNED] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "SMALLINT",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "SMALLINT UNSIGNED",
+        "5",
+        "5",
+        "",
+        "",
+        "[(M)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "1",
+        "0",
+        "1",
+        "SMALLINT UNSIGNED",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "FLOAT",
+        "7",
+        "10",
+        "",
+        "",
+        "[(M|D)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "1",
+        "FLOAT",
+        "-38",
+        "38",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "DOUBLE",
+        "8",
+        "17",
+        "",
+        "",
+        "[(M|D)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "1",
+        "DOUBLE",
+        "-308",
+        "308",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "DOUBLE PRECISION",
+        "8",
+        "17",
+        "",
+        "",
+        "[(M,D)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "1",
+        "DOUBLE PRECISION",
+        "-308",
+        "308",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "REAL",
+        "8",
+        "17",
+        "",
+        "",
+        "[(M,D)] [ZEROFILL]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "1",
+        "REAL",
+        "-308",
+        "308",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "VARCHAR", "12", "255", "'", "'", "(M)", "1", "0", "3", "0", "0", "0", "VARCHAR", "0", "0",
+        "0", "0", "10"
+      },
+      {
+        "ENUM", "12", "65535", "'", "'", "", "1", "0", "3", "0", "0", "0", "ENUM", "0", "0", "0",
+        "0", "10"
+      },
+      {
+        "SET", "12", "64", "'", "'", "", "1", "0", "3", "0", "0", "0", "SET", "0", "0", "0", "0",
+        "10"
+      },
+      {
+        "DATE", "91", "10", "'", "'", "", "1", "0", "3", "0", "0", "0", "DATE", "0", "0", "0", "0",
+        "10"
+      },
+      {
+        "TIME", "92", "18", "'", "'", "[(M)]", "1", "0", "3", "0", "0", "0", "TIME", "0", "0", "0",
+        "0", "10"
+      },
+      {
+        "DATETIME",
+        "93",
+        "27",
+        "'",
+        "'",
+        "[(M)]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "0",
+        "DATETIME",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      },
+      {
+        "TIMESTAMP",
+        "93",
+        "27",
+        "'",
+        "'",
+        "[(M)]",
+        "1",
+        "0",
+        "3",
+        "0",
+        "0",
+        "0",
+        "TIMESTAMP",
+        "0",
+        "0",
+        "0",
+        "0",
+        "10"
+      }
+    };
+
+    return CompleteResult.createResultSet(columnNames, dataTypes, data, connection.getContext(), 0);
+  }
+
+  /**
+   * Retrieves a description of the given table's indices and statistics. They are ordered by
+   * NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
+   *
+   * <p>Each index column description has the following columns:
+   *
+   * <ol>
+   *   <li><B>TABLE_CAT</B> String {@code =>} table catalog (may be <code>null</code>)
+   *   <li><B>TABLE_SCHEM</B> String {@code =>} table schema (may be <code>null</code>)
+   *   <li><B>TABLE_NAME</B> String {@code =>} table name
+   *   <li><B>NON_UNIQUE</B> boolean {@code =>} Can index values be non-unique. false when TYPE is
+   *       tableIndexStatistic
+   *   <li><B>INDEX_QUALIFIER</B> String {@code =>} index catalog (may be <code>null</code>); <code>
+   *       null</code> when TYPE is tableIndexStatistic
+   *   <li><B>INDEX_NAME</B> String {@code =>} index name; <code>null</code> when TYPE is
+   *       tableIndexStatistic
+   *   <li><B>TYPE</B> short {@code =>} index type:
+   *       <ul>
+   *         <li>tableIndexStatistic - this identifies table statistics that are returned in
+   *             conjuction with a table's index descriptions
+   *         <li>tableIndexClustered - this is a clustered index
+   *         <li>tableIndexHashed - this is a hashed index
+   *         <li>tableIndexOther - this is some other style of index
+   *       </ul>
+   *   <li><B>ORDINAL_POSITION</B> short {@code =>} column sequence number within index; zero when
+   *       TYPE is tableIndexStatistic
+   *   <li><B>COLUMN_NAME</B> String {@code =>} column name; <code>null</code> when TYPE is
+   *       tableIndexStatistic
+   *   <li><B>ASC_OR_DESC</B> String {@code =>} column sort sequence, "A" {@code =>} ascending, "D"
+   *       {@code =>} descending, may be <code>null</code> if sort sequence is not supported; <code>
+   *       null</code> when TYPE is tableIndexStatistic
+   *   <li><B>CARDINALITY</B> long {@code =>} When TYPE is tableIndexStatistic, then this is the
+   *       number of rows in the table; otherwise, it is the number of unique values in the index.
+   *   <li><B>PAGES</B> long {@code =>} When TYPE is tableIndexStatisic then this is the number of
+   *       pages used for the table, otherwise it is the number of pages used for the current index.
+   *   <li><B>FILTER_CONDITION</B> String {@code =>} Filter condition, if any. (may be <code>null
+   *       </code>)
+   * </ol>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in this database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schema a schema name; must match the schema name as it is stored in this database; ""
+   *     retrieves those without a schema; <code>null</code> means that the schema name should not
+   *     be used to narrow the search
+   * @param table a table name; must match the table name as it is stored in this database
+   * @param unique when true, return only indices for unique values; when false, return indices
+   *     regardless of whether unique or not
+   * @param approximate when true, result is allowed to reflect approximate or out of data values;
+   *     when false, results are requested to be accurate
+   * @return <code>ResultSet</code> - each row is an index column description
+   * @throws SQLException if a database access error occurs
+   */
+  public ResultSet getIndexInfo(
+      String catalog, String schema, String table, boolean unique, boolean approximate)
+      throws SQLException {
+    if (table == null) {
+      throw new SQLException("'table' parameter must not be null");
+    }
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT TABLE_SCHEMA TABLE_CAT, "
+                + "NULL TABLE_SCHEM, "
+                + "TABLE_NAME, "
+                + "NON_UNIQUE, "
+                + "TABLE_SCHEMA INDEX_QUALIFIER, "
+                + "INDEX_NAME, "
+                + tableIndexOther
+                + " TYPE, "
+                + "SEQ_IN_INDEX ORDINAL_POSITION, "
+                + "COLUMN_NAME, "
+                + "COLLATION ASC_OR_DESC, "
+                + "CARDINALITY, "
+                + "NULL PAGES, "
+                + "NULL FILTER_CONDITION"
+                + " FROM INFORMATION_SCHEMA.STATISTICS");
+
+    boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
+    sb.append(firstCondition ? " WHERE " : " AND ")
+        .append("TABLE_NAME = ")
+        .append(escapeQuote(table));
+    if (unique) sb.append(" AND NON_UNIQUE = 0");
+    sb.append(" ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION");
+
+    return executeQuery(sb.toString());
+  }
+
+  /**
+   * Retrieves whether this database supports the given result set type. ResultSet.TYPE_FORWARD_ONLY
+   * and ResultSet.TYPE_SCROLL_INSENSITIVE are supported.
+   *
+   * @param type one of the following <code>ResultSet</code> constants:
+   *     <ul>
+   *       <li><code>ResultSet.TYPE_FORWARD_ONLY</code>
+   *       <li><code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
+   *       <li><code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+   *     </ul>
+   *
+   * @return true if supported
+   */
+  public boolean supportsResultSetType(int type) {
+    return (type == ResultSet.TYPE_SCROLL_INSENSITIVE || type == ResultSet.TYPE_FORWARD_ONLY);
+  }
+
+  /**
+   * Retrieves whether this database supports the given concurrency type in combination with the
+   * given result set type. All are supported, but combination that use
+   * ResultSet.TYPE_SCROLL_INSENSITIVE.
+   *
+   * @param type one of the following <code>ResultSet</code> constants:
+   *     <ul>
+   *       <li><code>ResultSet.TYPE_FORWARD_ONLY</code>
+   *       <li><code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>
+   *       <li><code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+   *     </ul>
+   *
+   * @param concurrency one of the following <code>ResultSet</code> constants:
+   *     <ul>
+   *       <li><code>ResultSet.CONCUR_READ_ONLY</code>
+   *       <li><code>ResultSet.CONCUR_UPDATABLE</code>
+   *     </ul>
+   *
+   * @return true if supported
+   */
+  public boolean supportsResultSetConcurrency(int type, int concurrency) {
+    // Support all concurrency (ResultSet.CONCUR_READ_ONLY and ResultSet.CONCUR_UPDATABLE)
+    // so just return scroll type
+    return type == ResultSet.TYPE_SCROLL_INSENSITIVE || type == ResultSet.TYPE_FORWARD_ONLY;
+  }
+
+  public boolean ownUpdatesAreVisible(int type) {
+    return supportsResultSetType(type);
+  }
+
+  public boolean ownDeletesAreVisible(int type) {
+    return supportsResultSetType(type);
+  }
+
+  public boolean ownInsertsAreVisible(int type) {
+    return supportsResultSetType(type);
+  }
+
+  public boolean othersUpdatesAreVisible(int type) {
+    return false;
+  }
+
+  public boolean othersDeletesAreVisible(int type) {
+    return false;
+  }
+
+  public boolean othersInsertsAreVisible(int type) {
+    return false;
+  }
+
+  public boolean updatesAreDetected(int type) {
+    return false;
+  }
+
+  public boolean deletesAreDetected(int type) {
+    return false;
+  }
+
+  public boolean insertsAreDetected(int type) {
+    return false;
+  }
+
+  public boolean supportsBatchUpdates() {
+    return true;
+  }
+
+  /**
+   * Retrieves a description of the user-defined types (UDTs) defined in a particular schema.
+   * Schema-specific UDTs may have type <code>JAVA_OBJECT</code>, <code>STRUCT</code>, or <code>
+   * DISTINCT</code>.
+   *
+   * <p>Only types matching the catalog, schema, type name and type criteria are returned. They are
+   * ordered by <code>DATA_TYPE</code>, <code>TYPE_CAT</code>, <code>TYPE_SCHEM</code> and <code>
+   * TYPE_NAME</code>. The type name parameter may be a fully-qualified name. In this case, the
+   * catalog and schemaPattern parameters are ignored.
+   *
+   * <p>Each type description has the following columns:
+   *
+   * <ol>
+   *   <li><B>TYPE_CAT</B> String {@code =>} the type's catalog (may be <code>null</code>)
+   *   <li><B>TYPE_SCHEM</B> String {@code =>} type's schema (may be <code>null</code>)
+   *   <li><B>TYPE_NAME</B> String {@code =>} type name
+   *   <li><B>CLASS_NAME</B> String {@code =>} Java class name
+   *   <li><B>DATA_TYPE</B> int {@code =>} type value defined in java.sql.Types. One of JAVA_OBJECT,
+   *       STRUCT, or DISTINCT
+   *   <li><B>REMARKS</B> String {@code =>} explanatory comment on the type
+   *   <li><B>BASE_TYPE</B> short {@code =>} type code of the source type of a DISTINCT type or the
+   *       type that implements the user-generated reference type of the SELF_REFERENCING_COLUMN of
+   *       a structured type as defined in java.sql.Types (<code>null</code> if DATA_TYPE is not
+   *       DISTINCT or not STRUCT with REFERENCE_GENERATION = USER_DEFINED)
+   * </ol>
+   *
+   * <p><B>Note:</B> If the driver does not support UDTs, an empty result set is returned.
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema pattern name; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param typeNamePattern a type name pattern; must match the type name as it is stored in the
+   *     database; may be a fully qualified name
+   * @param types a list of user-defined types (JAVA_OBJECT, STRUCT, or DISTINCT) to include; <code>
+   *     null</code> returns all types
+   * @return <code>ResultSet</code> object in which each row describes a UDT
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   * @since 1.2
+   */
+  @Override
+  public ResultSet getUDTs(
+      String catalog, String schemaPattern, String typeNamePattern, int[] types)
+      throws SQLException {
+    String sql =
+        "SELECT ' ' TYPE_CAT, NULL TYPE_SCHEM, ' ' TYPE_NAME, ' ' CLASS_NAME, 0 DATA_TYPE, ' '"
+            + " REMARKS, 0 BASE_TYPE FROM DUAL WHERE 1=0";
+
+    return executeQuery(sql);
+  }
+
+  public org.mariadb.jdbc.Connection getConnection() {
+    return connection;
+  }
+
+  public boolean supportsSavepoints() {
+    return true;
+  }
+
+  public boolean supportsNamedParameters() {
+    return false;
+  }
+
+  public boolean supportsMultipleOpenResults() {
+    return false;
+  }
+
+  public boolean supportsGetGeneratedKeys() {
+    return true;
+  }
+
+  /**
+   * Retrieves a description of the user-defined type (UDT) hierarchies defined in a particular
+   * schema in this database. Only the immediate super type/ subtype relationship is modeled. Only
+   * supertype information for UDTs matching the catalog, schema, and type name is returned. The
+   * type name parameter may be a fully-qualified name. When the UDT name supplied is a
+   * fully-qualified name, the catalog and schemaPattern parameters are ignored. If a UDT does not
+   * have a direct super type, it is not listed here. A row of the <code>ResultSet</code> object
+   * returned by this method describes the designated UDT and a direct supertype. A row has the
+   * following columns:
+   *
+   * <OL>
+   *   <li><B>TYPE_CAT</B> String {@code =>} the UDT's catalog (may be <code>null</code>)
+   *   <li><B>TYPE_SCHEM</B> String {@code =>} UDT's schema (may be <code>null</code>)
+   *   <li><B>TYPE_NAME</B> String {@code =>} type name of the UDT
+   *   <li><B>SUPERTYPE_CAT</B> String {@code =>} the direct super type's catalog (may be <code>null
+   *       </code>)
+   *   <li><B>SUPERTYPE_SCHEM</B> String {@code =>} the direct super type's schema (may be <code>
+   *       null</code>)
+   *   <li><B>SUPERTYPE_NAME</B> String {@code =>} the direct super type's name
+   * </OL>
+   *
+   * <p><B>Note:</B> If the driver does not support type hierarchies, an empty result set is
+   * returned.
+   *
+   * @param catalog a catalog name; "" retrieves those without a catalog; <code>null</code> means
+   *     drop catalog name from the selection criteria
+   * @param schemaPattern a schema name pattern; "" retrieves those without a schema
+   * @param typeNamePattern a UDT name pattern; may be a fully-qualified name
+   * @return a <code>ResultSet</code> object in which a row gives information about the designated
+   *     UDT
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   * @since 1.4
+   */
+  public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern)
+      throws SQLException {
+    String sql =
+        "SELECT  ' ' TYPE_CAT, NULL TYPE_SCHEM, ' ' TYPE_NAME, ' ' SUPERTYPE_CAT, ' '"
+            + " SUPERTYPE_SCHEM, ' '  SUPERTYPE_NAME FROM DUAL WHERE 1=0";
+
+    return executeQuery(sql);
+  }
+
+  /**
+   * Retrieves a description of the table hierarchies defined in a particular schema in this
+   * database.
+   *
+   * <p>Only supertable information for tables matching the catalog, schema and table name are
+   * returned. The table name parameter may be a fully-qualified name, in which case, the catalog
+   * and schemaPattern parameters are ignored. If a table does not have a super table, it is not
+   * listed here. Supertables have to be defined in the same catalog and schema as the sub tables.
+   * Therefore, the type description does not need to include this information for the supertable.
+   *
+   * <p>Each type description has the following columns:
+   *
+   * <OL>
+   *   <li><B>TABLE_CAT</B> String {@code =>} the type's catalog (may be <code>null</code>)
+   *   <li><B>TABLE_SCHEM</B> String {@code =>} type's schema (may be <code>null</code>)
+   *   <li><B>TABLE_NAME</B> String {@code =>} type name
+   *   <li><B>SUPERTABLE_NAME</B> String {@code =>} the direct super type's name
+   * </OL>
+   *
+   * <p><B>Note:</B> If the driver does not support type hierarchies, an empty result set is
+   * returned.
+   *
+   * @param catalog a catalog name; "" retrieves those without a catalog; <code>null</code> means
+   *     drop catalog name from the selection criteria
+   * @param schemaPattern a schema name pattern; "" retrieves those without a schema
+   * @param tableNamePattern a table name pattern; may be a fully-qualified name
+   * @return a <code>ResultSet</code> object in which each row is a type description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   * @since 1.4
+   */
+  public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern)
+      throws SQLException {
+    String sql =
+        "SELECT  ' ' TABLE_CAT, ' ' TABLE_SCHEM, ' ' TABLE_NAME, ' ' SUPERTABLE_NAME FROM DUAL"
+            + " WHERE 1=0";
+    return executeQuery(sql);
+  }
+
+  /**
+   * Retrieves a description of the given attribute of the given type for a user-defined type (UDT)
+   * that is available in the given schema and catalog. Descriptions are returned only for
+   * attributes of UDTs matching the catalog, schema, type, and attribute name criteria. They are
+   * ordered by <code>TYPE_CAT</code>, <code>TYPE_SCHEM</code>, <code>TYPE_NAME</code> and <code>
+   * ORDINAL_POSITION</code>. This description does not contain inherited attributes. The <code>
+   * ResultSet</code> object that is returned has the following columns:
+   *
+   * <OL>
+   *   <li><B>TYPE_CAT</B> String {@code =>} type catalog (may be <code>null</code>)
+   *   <li><B>TYPE_SCHEM</B> String {@code =>} type schema (may be <code>null</code>)
+   *   <li><B>TYPE_NAME</B> String {@code =>} type name
+   *   <li><B>ATTR_NAME</B> String {@code =>} attribute name
+   *   <li><B>DATA_TYPE</B> int {@code =>} attribute type SQL type from java.sql.Types
+   *   <li><B>ATTR_TYPE_NAME</B> String {@code =>} Data source dependent type name. For a UDT, the
+   *       type name is fully qualified. For a REF, the type name is fully qualified and represents
+   *       the target type of the reference type.
+   *   <li><B>ATTR_SIZE</B> int {@code =>} column size. For char or date types this is the maximum
+   *       number of characters; for numeric or decimal types this is precision.
+   *   <li><B>DECIMAL_DIGITS</B> int {@code =>} the number of fractional digits. Null is returned
+   *       for data types where DECIMAL_DIGITS is not applicable.
+   *   <li><B>NUM_PREC_RADIX</B> int {@code =>} Radix (typically either 10 or 2)
+   *   <li><B>NULLABLE</B> int {@code =>} whether NULL is allowed
+   *       <UL>
+   *         <li>attributeNoNulls - might not allow NULL values
+   *         <li>attributeNullable - definitely allows NULL values
+   *         <li>attributeNullableUnknown - nullability unknown
+   *       </UL>
+   *   <li><B>REMARKS</B> String {@code =>} comment describing column (may be <code>null</code>)
+   *   <li><B>ATTR_DEF</B> String {@code =>} default value (may be<code>null</code>)
+   *   <li><B>SQL_DATA_TYPE</B> int {@code =>} unused
+   *   <li><B>SQL_DATETIME_SUB</B> int {@code =>} unused
+   *   <li><B>CHAR_OCTET_LENGTH</B> int {@code =>} for char types the maximum number of bytes in the
+   *       column
+   *   <li><B>ORDINAL_POSITION</B> int {@code =>} index of the attribute in the UDT (starting at 1)
+   *   <li><B>IS_NULLABLE</B> String {@code =>} ISO rules are used to determine the nullability for
+   *       a attribute.
+   *       <UL>
+   *         <li>YES --- if the attribute can include NULLs
+   *         <li>NO --- if the attribute cannot include NULLs
+   *         <li>empty string --- if the nullability for the attribute is unknown
+   *       </UL>
+   *   <li><B>SCOPE_CATALOG</B> String {@code =>} catalog of table that is the scope of a reference
+   *       attribute (<code>null</code> if DATA_TYPE isn't REF)
+   *   <li><B>SCOPE_SCHEMA</B> String {@code =>} schema of table that is the scope of a reference
+   *       attribute (<code>null</code> if DATA_TYPE isn't REF)
+   *   <li><B>SCOPE_TABLE</B> String {@code =>} table name that is the scope of a reference
+   *       attribute (<code>null</code> if the DATA_TYPE isn't REF)
+   *   <li><B>SOURCE_DATA_TYPE</B> short {@code =>} source type of a distinct type or user-generated
+   *       Ref type,SQL type from java.sql.Types (<code>null</code> if DATA_TYPE isn't DISTINCT or
+   *       user-generated REF)
+   * </OL>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param typeNamePattern a type name pattern; must match the type name as it is stored in the
+   *     database
+   * @param attributeNamePattern an attribute name pattern; must match the attribute name as it is
+   *     declared in the database
+   * @return a <code>ResultSet</code> object in which each row is an attribute description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   * @since 1.4
+   */
+  public ResultSet getAttributes(
+      String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern)
+      throws SQLException {
+
+    String sql =
+        "SELECT ' ' TYPE_CAT, ' ' TYPE_SCHEM, ' ' TYPE_NAME, ' ' ATTR_NAME, 0 DATA_TYPE, ' '"
+            + " ATTR_TYPE_NAME, 0 ATTR_SIZE, 0 DECIMAL_DIGITS, 0 NUM_PREC_RADIX, 0 NULLABLE, ' '"
+            + " REMARKS, ' ' ATTR_DEF,  0 SQL_DATA_TYPE, 0 SQL_DATETIME_SUB, 0 CHAR_OCTET_LENGTH, 0"
+            + " ORDINAL_POSITION, ' ' IS_NULLABLE, ' ' SCOPE_CATALOG, ' ' SCOPE_SCHEMA, ' '"
+            + " SCOPE_TABLE, 0 SOURCE_DATA_TYPE FROM DUAL  WHERE 1=0";
+
+    return executeQuery(sql);
+  }
+
+  public boolean supportsResultSetHoldability(int holdability) {
+    return holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+  public int getResultSetHoldability() {
+    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+  public int getDatabaseMajorVersion() {
+    return connection.getContext().getVersion().getMajorVersion();
+  }
+
+  public int getDatabaseMinorVersion() {
+    return connection.getContext().getVersion().getMinorVersion();
+  }
+
+  @Override
+  public int getJDBCMajorVersion() {
+    return 4;
+  }
+
+  @Override
+  public int getJDBCMinorVersion() {
+    return 2;
+  }
+
+  @Override
+  public int getSQLStateType() {
+    return sqlStateSQL99;
+  }
+
+  public boolean locatorsUpdateCopy() {
+    return false;
+  }
+
+  public boolean supportsStatementPooling() {
+    return false;
+  }
+
+  public RowIdLifetime getRowIdLifetime() {
+    return RowIdLifetime.ROWID_UNSUPPORTED;
+  }
+
+  public boolean supportsStoredFunctionsUsingCallSyntax() {
+    return true;
+  }
+
+  public boolean autoCommitFailureClosesAllResultSets() {
+    return false;
+  }
+
+  /**
+   * Retrieves a list of the client info properties that the driver supports. The result set
+   * contains the following columns
+   *
+   * <ol>
+   *   <li>NAME String : The name of the client info property
+   *   <li>MAX_LEN int : The maximum length of the value for the property
+   *   <li>DEFAULT_VALUE String : The default value of the property
+   *   <li>DESCRIPTION String : A description of the property. This will typically contain
+   *       information as to where this property is stored in the database.
+   * </ol>
+   *
+   * <p>The ResultSet is sorted by the NAME column
+   *
+   * @return A ResultSet object; each row is a supported client info property
+   */
+  public ResultSet getClientInfoProperties() {
+    String[] columnNames = new String[] {"NAME", "MAX_LEN", "DEFAULT_VALUE", "DESCRIPTION"};
+
+    DataType[] types =
+        new DataType[] {
+          DataType.VARSTRING, DataType.INTEGER, DataType.VARSTRING, DataType.VARSTRING
+        };
+    String[][] data =
+        new String[][] {
+          new String[] {
+            "ApplicationName",
+            "16777215",
+            "",
+            "The name of the application currently utilizing the connection"
+          },
+          new String[] {
+            "ClientUser",
+            "16777215",
+            "",
+            "The name of the user that the application using the connection is performing work for."
+                + " This may not be the same as the user name that was used in establishing the"
+                + " connection."
+          },
+          new String[] {
+            "ClientHostname",
+            "16777215",
+            "",
+            "The hostname of the computer the application using the connection is running on"
+          }
+        };
+
+    return CompleteResult.createResultSet(columnNames, types, data, connection.getContext(), 0);
+  }
+
+  /**
+   * Retrieves a description of the system and user functions available in the given catalog. Only
+   * system and user function descriptions matching the schema and function name criteria are
+   * returned. They are ordered by <code>FUNCTION_CAT</code>, <code>FUNCTION_SCHEM</code>, <code>
+   * FUNCTION_NAME</code> and <code>SPECIFIC_ NAME</code>.
+   *
+   * <p>Each function description has the following columns:
+   *
+   * <OL>
+   *   <li><B>FUNCTION_CAT</B> String {@code =>} function catalog (may be <code>null</code>)
+   *   <li><B>FUNCTION_SCHEM</B> String {@code =>} function schema (may be <code>null</code>)
+   *   <li><B>FUNCTION_NAME</B> String {@code =>} function name. This is the name used to invoke the
+   *       function
+   *   <li><B>REMARKS</B> String {@code =>} explanatory comment on the function
+   *   <li><B>FUNCTION_TYPE</B> short {@code =>} kind of function:
+   *       <UL>
+   *         <li>functionResultUnknown - Cannot determine if a return value or table will be
+   *             returned
+   *         <li>functionNoTable- Does not return a table
+   *         <li>functionReturnsTable - Returns a table
+   *       </UL>
+   *   <li><B>SPECIFIC_NAME</B> String {@code =>} the name which uniquely identifies this function
+   *       within its schema. This is a user specified, or DBMS generated, name that may be
+   *       different then the <code>FUNCTION_NAME</code> for example with overload functions
+   * </OL>
+   *
+   * <p>A user may not have permission to execute any of the functions that are returned by <code>
+   * getFunctions</code>
+   *
+   * @param catalog a catalog name; must match the catalog name as it is stored in the database; ""
+   *     retrieves those without a catalog; <code>null</code> means that the catalog name should not
+   *     be used to narrow the search
+   * @param schemaPattern a schema name pattern; must match the schema name as it is stored in the
+   *     database; "" retrieves those without a schema; <code>null</code> means that the schema name
+   *     should not be used to narrow the search
+   * @param functionNamePattern a function name pattern; must match the function name as it is
+   *     stored in the database
+   * @return <code>ResultSet</code> - each row is a function description
+   * @throws SQLException if a database access error occurs
+   * @see #getSearchStringEscape
+   * @since 1.6
+   */
+  public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
+      throws SQLException {
+    StringBuilder sb =
+        new StringBuilder(
+            "SELECT ROUTINE_SCHEMA FUNCTION_CAT,"
+                + "NULL FUNCTION_SCHEM, "
+                + "ROUTINE_NAME FUNCTION_NAME, "
+                + "ROUTINE_COMMENT REMARKS, "
+                + functionNoTable
+                + " FUNCTION_TYPE, "
+                + "SPECIFIC_NAME "
+                + " FROM INFORMATION_SCHEMA.ROUTINES");
+    boolean firstCondition = catalogCond(true, sb, "ROUTINE_SCHEMA", catalog);
+    firstCondition = patternCond(firstCondition, sb, "ROUTINE_NAME", functionNamePattern);
+    sb.append(firstCondition ? " WHERE " : " AND ").append(" ROUTINE_TYPE='FUNCTION'");
+
+    return executeQuery(sb.toString());
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+
+  @Override
+  public long getMaxLogicalLobSize() {
+    return 4294967295L;
+  }
+
+  private static class Identifier {
+    public String schema;
+    public String name;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/Driver.java b/src/main/java/org/mariadb/jdbc/Driver.java
new file mode 100644
index 0000000..db5da27
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/Driver.java
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.impl.MultiPrimaryClient;
+import org.mariadb.jdbc.client.impl.MultiPrimaryReplicaClient;
+import org.mariadb.jdbc.client.impl.ReplayClient;
+import org.mariadb.jdbc.client.impl.StandardClient;
+import org.mariadb.jdbc.pool.Pools;
+import org.mariadb.jdbc.util.VersionFactory;
+
+/** MariaDB Driver */
+public final class Driver implements java.sql.Driver {
+
+  static {
+    try {
+      DriverManager.registerDriver(new Driver());
+    } catch (SQLException e) {
+      // eat
+    }
+  }
+
+  /**
+   * Connect according to configuration
+   *
+   * @param configuration configuration
+   * @return a Connection
+   * @throws SQLException if connect fails
+   */
+  public static Connection connect(Configuration configuration) throws SQLException {
+    ReentrantLock lock = new ReentrantLock();
+    Client client;
+    switch (configuration.haMode()) {
+      case LOADBALANCE:
+      case SEQUENTIAL:
+        client = new MultiPrimaryClient(configuration, lock);
+        break;
+
+      case REPLICATION:
+        // additional check
+        client = new MultiPrimaryReplicaClient(configuration, lock);
+        break;
+
+      default:
+        ClientInstance<Configuration, HostAddress, ReentrantLock, Boolean, Client> clientInstance =
+            (configuration.transactionReplay()) ? ReplayClient::new : StandardClient::new;
+
+        if (configuration.addresses().isEmpty()) {
+          // unix socket / windows pipe
+          client = clientInstance.apply(configuration, null, lock, false);
+        } else {
+          // loop until finding
+          SQLException lastException = null;
+          for (HostAddress host : configuration.addresses()) {
+            try {
+              client = clientInstance.apply(configuration, host, lock, false);
+              return new Connection(configuration, lock, client);
+            } catch (SQLException e) {
+              lastException = e;
+            }
+          }
+          throw lastException;
+        }
+        break;
+    }
+    return new Connection(configuration, lock, client);
+  }
+
+  @FunctionalInterface
+  private interface ClientInstance<T, U, V, W, R> {
+    R apply(T t, U u, V v, W w) throws SQLException;
+  }
+
+  /**
+   * Connect to the given connection string.
+   *
+   * @param url the url to connect to
+   * @return a connection
+   * @throws SQLException if it is not possible to connect
+   */
+  public Connection connect(final String url, final Properties props) throws SQLException {
+    Configuration configuration = Configuration.parse(url, props);
+    if (configuration != null) {
+      if (configuration.pool()) {
+        return Pools.retrievePool(configuration).getPoolConnection().getConnection();
+      }
+      return connect(configuration);
+    }
+    return null;
+  }
+
+  /**
+   * returns true if the driver can accept the url.
+   *
+   * @param url the url to test
+   * @return true if the url is valid for this driver
+   */
+  @Override
+  public boolean acceptsURL(String url) {
+    return Configuration.acceptsUrl(url);
+  }
+
+  /**
+   * Get the property info.
+   *
+   * @param url the url to get properties for
+   * @param info the info props
+   * @return all possible connector options
+   * @throws SQLException if there is a problem getting the property info
+   */
+  public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+    Configuration conf = Configuration.parse(url, info);
+    if (conf == null) {
+      return new DriverPropertyInfo[0];
+    }
+
+    Properties propDesc = new Properties();
+    try (InputStream inputStream =
+        Driver.class.getClassLoader().getResourceAsStream("driver.properties")) {
+      propDesc.load(inputStream);
+    } catch (IOException io) {
+      // eat
+    }
+
+    List<DriverPropertyInfo> props = new ArrayList<>();
+    for (Field field : Configuration.Builder.class.getDeclaredFields()) {
+      if (!field.getName().startsWith("_")) {
+        try {
+          Field fieldConf = Configuration.class.getDeclaredField(field.getName());
+          fieldConf.setAccessible(true);
+          Object obj = fieldConf.get(conf);
+          String value = obj == null ? null : obj.toString();
+          DriverPropertyInfo propertyInfo = new DriverPropertyInfo(field.getName(), value);
+          propertyInfo.description = value == null ? "" : (String) propDesc.get(field.getName());
+          propertyInfo.required = false;
+          props.add(propertyInfo);
+        } catch (IllegalAccessException | NoSuchFieldException e) {
+          // eat error
+        }
+      }
+    }
+    return props.toArray(new DriverPropertyInfo[0]);
+  }
+
+  /**
+   * gets the major version of the driver.
+   *
+   * @return the major versions
+   */
+  public int getMajorVersion() {
+    return VersionFactory.getInstance().getMajorVersion();
+  }
+
+  /**
+   * gets the minor version of the driver.
+   *
+   * @return the minor version
+   */
+  public int getMinorVersion() {
+    return VersionFactory.getInstance().getMinorVersion();
+  }
+
+  /**
+   * checks if the driver is jdbc compliant.
+   *
+   * @return true since the driver is not compliant
+   */
+  public boolean jdbcCompliant() {
+    return true;
+  }
+
+  public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+    throw new SQLFeatureNotSupportedException("Use logging parameters for enabling logging.");
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/FunctionStatement.java b/src/main/java/org/mariadb/jdbc/FunctionStatement.java
new file mode 100644
index 0000000..c40df49
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/FunctionStatement.java
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.*;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.util.ParameterList;
+
+/** Function callable statement implementation */
+public class FunctionStatement extends BaseCallableStatement implements CallableStatement {
+  /**
+   * Constructor of function callable statement
+   *
+   * @param con current connection
+   * @param databaseName database
+   * @param procedureName procedure
+   * @param arguments arguments
+   * @param lock thread lock object
+   * @param canUseServerTimeout can use server timeout
+   * @param canUseServerMaxRows can use server max rows
+   * @param canCachePrepStmts can cache server prepared result
+   * @param resultSetType result set type
+   * @param resultSetConcurrency concurrency type
+   * @throws SQLException if any error occurs
+   */
+  public FunctionStatement(
+      Connection con,
+      String databaseName,
+      String procedureName,
+      String arguments,
+      ReentrantLock lock,
+      boolean canUseServerTimeout,
+      boolean canUseServerMaxRows,
+      boolean canCachePrepStmts,
+      int resultSetType,
+      int resultSetConcurrency)
+      throws SQLException {
+    super(
+        "SELECT " + procedureName + arguments,
+        con,
+        lock,
+        databaseName,
+        procedureName,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        canCachePrepStmts,
+        resultSetType,
+        resultSetConcurrency,
+        0);
+    registerOutParameter(1, null);
+  }
+
+  @Override
+  public boolean isFunction() {
+    return true;
+  }
+
+  @Override
+  protected void handleParameterOutput() throws SQLException {
+    this.outputResultFromRes(1);
+  }
+
+  @Override
+  public void registerOutParameter(int index, int sqlType) throws SQLException {
+    if (index != 1) {
+      throw con.getExceptionFactory()
+          .of(this)
+          .create(String.format("wrong parameter index %s", index));
+    }
+    super.registerOutParameter(index, sqlType);
+  }
+
+  @Override
+  protected void executeInternal() throws SQLException {
+    preValidParameters();
+    super.executeInternal();
+  }
+
+  /**
+   * Ensures that returning value is not taken as a parameter.
+   *
+   * @throws SQLException if any exception
+   */
+  protected void preValidParameters() throws SQLException {
+    // remove first parameter, as it's an output param only
+    Parameters newParameters = new ParameterList(parameters.size() - 1);
+    for (int i = 0; i < parameters.size() - 1; i++) {
+      newParameters.set(i, parameters.get(i + 1));
+    }
+    parameters = newParameters;
+    super.validParameters();
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("FunctionStatement{sql:'" + sql + "'");
+    sb.append(", parameters:[");
+    for (int i = 0; i < parameters.size(); i++) {
+      org.mariadb.jdbc.client.util.Parameter param = parameters.get(i);
+      if (outputParameters.contains(i + 1)) sb.append("<OUT>");
+      if (param == null) {
+        sb.append("null");
+      } else {
+        sb.append(param.bestEffortStringValue(con.getContext()));
+      }
+      if (i != parameters.size() - 1) {
+        sb.append(",");
+      }
+    }
+    sb.append("]}");
+    return sb.toString();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/HostAddress.java b/src/main/java/org/mariadb/jdbc/HostAddress.java
new file mode 100644
index 0000000..f489b56
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/HostAddress.java
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import org.mariadb.jdbc.export.HaMode;
+
+/** Host entry */
+public class HostAddress {
+
+  /** host address */
+  public final String host;
+
+  /** port */
+  public int port;
+
+  /** primary node */
+  public Boolean primary;
+
+  /**
+   * Constructor.
+   *
+   * @param host host
+   * @param port port
+   * @param primary is primary
+   */
+  private HostAddress(String host, int port, Boolean primary) {
+    this.host = host;
+    this.port = port;
+    this.primary = primary;
+  }
+
+  /**
+   * Create a Host without knowledge of primary/replica goal
+   *
+   * @param host host (DNS/IP)
+   * @param port port
+   * @return host
+   */
+  public static HostAddress from(String host, int port) {
+    return new HostAddress(host, port, null);
+  }
+
+  /**
+   * Create a Host
+   *
+   * @param host host (DNS/IP)
+   * @param port port
+   * @param primary is primary
+   * @return host
+   */
+  public static HostAddress from(String host, int port, boolean primary) {
+    return new HostAddress(host, port, primary);
+  }
+
+  /**
+   * parse - parse server addresses from the URL fragment.
+   *
+   * @param spec list of endpoints in one of the forms 1 - host1,....,hostN:port (missing port
+   *     default to MariaDB default 3306 2 - host:port,...,host:port
+   * @param haMode High availability mode
+   * @throws SQLException for wrong spec
+   * @return parsed endpoints
+   */
+  public static List<HostAddress> parse(String spec, HaMode haMode) throws SQLException {
+    if ("".equals(spec)) {
+      return new ArrayList<>(0);
+    }
+    String[] tokens = spec.trim().split(",");
+    int size = tokens.length;
+    List<HostAddress> arr = new ArrayList<>(size);
+
+    for (int i = 0; i < tokens.length; i++) {
+      String token = tokens[i];
+      if (token.startsWith("address=")) {
+        arr.add(parseParameterHostAddress(token, haMode, i == 0));
+      } else {
+        arr.add(parseSimpleHostAddress(token, haMode, i == 0));
+      }
+    }
+
+    return arr;
+  }
+
+  private static HostAddress parseSimpleHostAddress(String str, HaMode haMode, boolean first)
+      throws SQLException {
+    String host;
+    int port = 3306;
+
+    if (str.charAt(0) == '[') {
+      /* IPv6 addresses in URLs are enclosed in square brackets */
+      int ind = str.indexOf(']');
+      host = str.substring(1, ind);
+      if (ind != (str.length() - 1) && str.charAt(ind + 1) == ':') {
+        port = getPort(str.substring(ind + 2));
+      }
+    } else if (str.contains(":")) {
+      /* Parse host:port */
+      String[] hostPort = str.split(":");
+      host = hostPort[0];
+      port = getPort(hostPort[1]);
+    } else {
+      /* Just host name is given */
+      host = str;
+    }
+
+    boolean primary = haMode != HaMode.REPLICATION || first;
+
+    return new HostAddress(host, port, primary);
+  }
+
+  private static int getPort(String portString) throws SQLException {
+    try {
+      return Integer.parseInt(portString);
+    } catch (NumberFormatException nfe) {
+      throw new SQLException("Incorrect port value : " + portString);
+    }
+  }
+
+  private static HostAddress parseParameterHostAddress(String str, HaMode haMode, boolean first)
+      throws SQLException {
+    String host = null;
+    int port = 3306;
+    Boolean primary = null;
+
+    String[] array = str.replace(" ", "").split("(?=\\()|(?<=\\))");
+    for (int i = 1; i < array.length; i++) {
+      String[] token = array[i].replace("(", "").replace(")", "").trim().split("=");
+      if (token.length != 2) {
+        throw new IllegalArgumentException(
+            "Invalid connection URL, expected key=value pairs, found " + array[i]);
+      }
+      String key = token[0].toLowerCase();
+      String value = token[1].toLowerCase();
+
+      switch (key) {
+        case "host":
+          host = value.replace("[", "").replace("]", "");
+          break;
+        case "port":
+          port = getPort(value);
+          break;
+        case "type":
+          if ("master".equalsIgnoreCase(value) || "primary".equalsIgnoreCase(value)) {
+            primary = true;
+          } else if ("slave".equalsIgnoreCase(value) || "replica".equalsIgnoreCase(value)) {
+            primary = false;
+          } else {
+            throw new SQLException(
+                String.format("Wrong type value %s (possible value primary/replica)", array[i]));
+          }
+          break;
+      }
+    }
+
+    if (primary == null) {
+      if (haMode == HaMode.REPLICATION) {
+        primary = first;
+      } else {
+        primary = true;
+      }
+    }
+
+    return new HostAddress(host, port, primary);
+  }
+
+  @Override
+  public String toString() {
+    return String.format(
+        "address=(host=%s)(port=%s)%s",
+        host, port, ((primary != null) ? ("(type=" + (primary ? "primary)" : "replica)")) : ""));
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    HostAddress that = (HostAddress) o;
+    return port == that.port
+        && Objects.equals(host, that.host)
+        && Objects.equals(primary, that.primary);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(host, port, primary);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/MariaDbBlob.java b/src/main/java/org/mariadb/jdbc/MariaDbBlob.java
new file mode 100644
index 0000000..c0ff330
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/MariaDbBlob.java
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.*;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.util.Arrays;
+
+/** MariaDB Blob implementation */
+public class MariaDbBlob implements Blob, Serializable {
+
+  private static final long serialVersionUID = -4736603161284649490L;
+
+  /** content */
+  protected byte[] data;
+
+  /** data offset */
+  protected transient int offset;
+
+  /** data length */
+  protected transient int length;
+
+  /** Creates an empty blob. */
+  public MariaDbBlob() {
+    data = new byte[0];
+    offset = 0;
+    length = 0;
+  }
+
+  /**
+   * Creates a blob with content.
+   *
+   * @param bytes the content for the blob.
+   */
+  public MariaDbBlob(byte[] bytes) {
+    if (bytes == null) {
+      throw new IllegalArgumentException("byte array is null");
+    }
+    data = bytes;
+    offset = 0;
+    length = bytes.length;
+  }
+
+  /**
+   * Creates a blob with content.
+   *
+   * @param bytes the content for the blob.
+   * @param offset offset
+   * @param length length
+   */
+  public MariaDbBlob(byte[] bytes, int offset, int length) {
+    if (bytes == null) {
+      throw new IllegalArgumentException("byte array is null");
+    }
+    data = bytes;
+    this.offset = offset;
+    this.length = Math.min(bytes.length - offset, length);
+  }
+
+  private MariaDbBlob(int offset, int length, byte[] bytes) {
+    this.data = bytes;
+    this.offset = offset;
+    this.length = length;
+  }
+
+  /**
+   * Return a new Blob from blob data
+   *
+   * @param bytes data
+   * @param offset data offset
+   * @param length data length
+   * @return new Blob
+   */
+  public static MariaDbBlob safeMariaDbBlob(byte[] bytes, int offset, int length) {
+    return new MariaDbBlob(offset, length, bytes);
+  }
+
+  /**
+   * Returns the number of bytes in the <code>BLOB</code> value designated by this <code>Blob</code>
+   * object.
+   *
+   * @return length of the <code>BLOB</code> in bytes
+   */
+  public long length() {
+    return length;
+  }
+
+  /**
+   * Retrieves all or part of the <code>BLOB</code> value that this <code>Blob</code> object
+   * represents, as an array of bytes. This <code>byte</code> array contains up to <code>length
+   * </code> consecutive bytes starting at position <code>pos</code>.
+   *
+   * @param pos the ordinal position of the first byte in the <code>BLOB</code> value to be
+   *     extracted; the first byte is at position 1
+   * @param length the number of consecutive bytes to be copied; the value for length must be 0 or
+   *     greater
+   * @return a byte array containing up to <code>length</code> consecutive bytes from the <code>BLOB
+   *     </code> value designated by this <code>Blob</code> object, starting with the byte at
+   *     position <code>pos</code>
+   * @throws SQLException if there is an error accessing the <code>BLOB</code> value; if pos is less
+   *     than 1 or length is less than 0
+   * @see #setBytes
+   * @since 1.2
+   */
+  public byte[] getBytes(final long pos, final int length) throws SQLException {
+    if (pos < 1) {
+      throw new SQLException(
+          String.format("Out of range (position should be > 0, but is %s)", pos));
+    }
+    final int offset = this.offset + (int) (pos - 1);
+    byte[] result = new byte[length];
+    System.arraycopy(data, offset, result, 0, Math.min(this.length - (int) (pos - 1), length));
+    return result;
+  }
+
+  /**
+   * Retrieves the <code>BLOB</code> value designated by this <code>Blob</code> instance as a
+   * stream.
+   *
+   * @return a stream containing the <code>BLOB</code> data
+   * @throws SQLException if something went wrong
+   * @see #setBinaryStream
+   */
+  public InputStream getBinaryStream() throws SQLException {
+    return getBinaryStream(1, length);
+  }
+
+  /**
+   * Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
+   * starting with the byte specified by pos, which is length bytes in length.
+   *
+   * @param pos the offset to the first byte of the partial value to be retrieved. The first byte in
+   *     the <code>Blob</code> is at position 1
+   * @param length the length in bytes of the partial value to be retrieved
+   * @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read.
+   * @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes in the
+   *     <code>Blob</code> or if pos + length is greater than the number of bytes in the <code>Blob
+   *     </code>
+   */
+  public InputStream getBinaryStream(final long pos, final long length) throws SQLException {
+    if (pos < 1) {
+      throw new SQLException("Out of range (position should be > 0)");
+    }
+    if (pos - 1 > this.length) {
+      throw new SQLException("Out of range (position > stream size)");
+    }
+    if (pos + length - 1 > this.length) {
+      throw new SQLException("Out of range (position + length - 1 > streamSize)");
+    }
+
+    return new ByteArrayInputStream(data, this.offset + (int) pos - 1, (int) length);
+  }
+
+  /**
+   * Retrieves the byte position at which the specified byte array <code>pattern</code> begins
+   * within the <code>BLOB</code> value that this <code>Blob</code> object represents. The search
+   * for <code>pattern</code> begins at position <code>start</code>.
+   *
+   * @param pattern the byte array for which to search
+   * @param start the position at which to begin searching; the first position is 1
+   * @return the position at which the pattern appears, else -1
+   */
+  public long position(final byte[] pattern, final long start) throws SQLException {
+    if (pattern.length == 0) {
+      return 0;
+    }
+    if (start < 1) {
+      throw new SQLException(
+          String.format("Out of range (position should be > 0, but is %s)", start));
+    }
+    if (start > this.length) {
+      throw new SQLException("Out of range (start > stream size)");
+    }
+
+    outer:
+    for (int i = (int) (offset + start - 1); i <= offset + this.length - pattern.length; i++) {
+      for (int j = 0; j < pattern.length; j++) {
+        if (data[i + j] != pattern[j]) {
+          continue outer;
+        }
+      }
+      return i + 1 - offset;
+    }
+    return -1;
+  }
+
+  /**
+   * Retrieves the byte position in the <code>BLOB</code> value designated by this <code>Blob</code>
+   * object at which <code>pattern</code> begins. The search begins at position <code>start</code>.
+   *
+   * @param pattern the <code>Blob</code> object designating the <code>BLOB</code> value for which
+   *     to search
+   * @param start the position in the <code>BLOB</code> value at which to begin searching; the first
+   *     position is 1
+   * @return the position at which the pattern begins, else -1
+   */
+  public long position(final Blob pattern, final long start) throws SQLException {
+    byte[] blobBytes = pattern.getBytes(1, (int) pattern.length());
+    return position(blobBytes, start);
+  }
+
+  /**
+   * Writes the given array of bytes to the <code>BLOB</code> value that this <code>Blob</code>
+   * object represents, starting at position <code>pos</code>, and returns the number of bytes
+   * written. The array of bytes will overwrite the existing bytes in the <code>Blob</code> object
+   * starting at the position <code>pos</code>. If the end of the <code>Blob</code> value is reached
+   * while writing the array of bytes, then the length of the <code>Blob</code> value will be
+   * increased to accommodate the extra bytes.
+   *
+   * @param pos the position in the <code>BLOB</code> object at which to start writing; the first
+   *     position is 1
+   * @param bytes the array of bytes to be written to the <code>BLOB</code> value that this <code>
+   *     Blob</code> object represents
+   * @return the number of bytes written
+   * @see #getBytes
+   */
+  public int setBytes(final long pos, final byte[] bytes) throws SQLException {
+    if (pos < 1) {
+      throw new SQLException("pos should be > 0, first position is 1.");
+    }
+
+    final int arrayPos = (int) pos - 1;
+
+    if (length > arrayPos + bytes.length) {
+
+      System.arraycopy(bytes, 0, data, offset + arrayPos, bytes.length);
+
+    } else {
+
+      byte[] newContent = new byte[arrayPos + bytes.length];
+      if (Math.min(arrayPos, length) > 0) {
+        System.arraycopy(data, this.offset, newContent, 0, Math.min(arrayPos, length));
+      }
+      System.arraycopy(bytes, 0, newContent, arrayPos, bytes.length);
+      data = newContent;
+      length = arrayPos + bytes.length;
+      offset = 0;
+    }
+    return bytes.length;
+  }
+
+  /**
+   * Writes all or part of the given <code>byte</code> array to the <code>BLOB</code> value that
+   * this <code>Blob</code> object represents and returns the number of bytes written. Writing
+   * starts at position <code>pos</code> in the <code>BLOB</code> value; <code>len</code> bytes from
+   * the given byte array are written. The array of bytes will overwrite the existing bytes in the
+   * <code>Blob</code> object starting at the position <code>pos</code>. If the end of the <code>
+   * Blob</code> value is reached while writing the array of bytes, then the length of the <code>
+   * Blob</code> value will be increased to accommodate the extra bytes.
+   *
+   * <p><b>Note:</b> If the value specified for <code>pos</code> is greater than the length+1 of the
+   * <code>BLOB</code> value then the behavior is undefined. Some JDBC drivers may throw a <code>
+   * SQLException</code> while other drivers may support this operation.
+   *
+   * @param pos the position in the <code>BLOB</code> object at which to start writing; the first
+   *     position is 1
+   * @param bytes the array of bytes to be written to this <code>BLOB</code> object
+   * @param offset the offset into the array <code>bytes</code> at which to start reading the bytes
+   *     to be set
+   * @param len the number of bytes to be written to the <code>BLOB</code> value from the array of
+   *     bytes <code>bytes</code>
+   * @return the number of bytes written
+   * @throws SQLException if there is an error accessing the <code>BLOB</code> value or if pos is
+   *     less than 1
+   * @see #getBytes
+   */
+  public int setBytes(final long pos, final byte[] bytes, final int offset, final int len)
+      throws SQLException {
+
+    if (pos < 1) {
+      throw new SQLException("pos should be > 0, first position is 1.");
+    }
+
+    final int arrayPos = (int) pos - 1;
+    final int byteToWrite = Math.min(bytes.length - offset, len);
+
+    if (length > arrayPos + byteToWrite) {
+
+      System.arraycopy(bytes, offset, data, this.offset + arrayPos, byteToWrite);
+
+    } else {
+
+      byte[] newContent = new byte[arrayPos + byteToWrite];
+      if (Math.min(arrayPos, length) > 0) {
+        System.arraycopy(data, this.offset, newContent, 0, Math.min(arrayPos, length));
+      }
+      System.arraycopy(bytes, offset, newContent, arrayPos, byteToWrite);
+      data = newContent;
+      length = arrayPos + byteToWrite;
+      this.offset = 0;
+    }
+
+    return byteToWrite;
+  }
+
+  /**
+   * Retrieves a stream that can be used to write to the <code>BLOB</code> value that this <code>
+   * Blob</code> object represents. The stream begins at position <code>pos</code>. The bytes
+   * written to the stream will overwrite the existing bytes in the <code>Blob</code> object
+   * starting at the position <code>pos</code>. If the end of the <code>Blob</code> value is reached
+   * while writing to the stream, then the length of the <code>Blob</code> value will be increased
+   * to accommodate the extra bytes.
+   *
+   * <p><b>Note:</b> If the value specified for <code>pos</code> is greater than the length+1 of the
+   * <code>BLOB</code> value then the behavior is undefined. Some JDBC drivers may throw a <code>
+   * SQLException</code> while other drivers may support this operation.
+   *
+   * @param pos the position in the <code>BLOB</code> value at which to start writing; the first
+   *     position is 1
+   * @return a <code>java.io.OutputStream</code> object to which data can be written
+   * @throws SQLException if there is an error accessing the <code>BLOB</code> value or if pos is
+   *     less than 1
+   * @see #getBinaryStream
+   * @since 1.4
+   */
+  public OutputStream setBinaryStream(final long pos) throws SQLException {
+    if (pos < 1) {
+      throw new SQLException("Invalid position in blob");
+    }
+    if (offset > 0) {
+      byte[] tmp = new byte[length];
+      System.arraycopy(data, offset, tmp, 0, length);
+      data = tmp;
+      offset = 0;
+    }
+    return new BlobOutputStream(this, (int) (pos - 1) + offset);
+  }
+
+  /**
+   * Truncates the <code>BLOB</code> value that this <code>Blob</code> object represents to be
+   * <code>len</code> bytes in length.
+   *
+   * @param len the length, in bytes, to which the <code>BLOB</code> value that this <code>Blob
+   *     </code> object represents should be truncated
+   */
+  public void truncate(final long len) {
+    if (len >= 0 && len < this.length) {
+      this.length = (int) len;
+    }
+  }
+
+  /**
+   * This method frees the <code>Blob</code> object and releases the resources that it holds. The
+   * object is invalid once the <code>free</code> method is called.
+   *
+   * <p>After <code>free</code> has been called, any attempt to invoke a method other than <code>
+   * free</code> will result in a <code>SQLException</code> being thrown. If <code>free</code> is
+   * called multiple times, the subsequent calls to <code>free</code> are treated as a no-op.
+   */
+  public void free() {
+    this.data = new byte[0];
+    this.offset = 0;
+    this.length = 0;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    MariaDbBlob that = (MariaDbBlob) o;
+
+    if (length != that.length) return false;
+
+    for (int i = 0; i < length; i++) {
+      if (data[offset + i] != that.data[that.offset + i]) return false;
+    }
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = Arrays.hashCode(data);
+    result = 31 * result + offset;
+    result = 31 * result + length;
+    return result;
+  }
+
+  static class BlobOutputStream extends OutputStream {
+
+    private final MariaDbBlob blob;
+    private int pos;
+
+    public BlobOutputStream(MariaDbBlob blob, int pos) {
+      this.blob = blob;
+      this.pos = pos;
+    }
+
+    @Override
+    public void write(int bit) {
+
+      if (this.pos >= blob.length) {
+        byte[] tmp = new byte[2 * blob.length + 1];
+        System.arraycopy(blob.data, blob.offset, tmp, 0, blob.length);
+        blob.data = tmp;
+        pos -= blob.offset;
+        blob.offset = 0;
+        blob.length++;
+      }
+      blob.data[pos++] = (byte) bit;
+    }
+
+    @Override
+    public void write(byte[] buf, int off, int len) throws IOException {
+      if (off < 0) {
+        throw new IOException("Invalid offset " + off);
+      }
+      if (len < 0) {
+        throw new IOException("Invalid len " + len);
+      }
+      int realLen = Math.min(buf.length - off, len);
+      if (pos + realLen >= blob.length) {
+        int newLen = 2 * blob.length + realLen;
+        byte[] tmp = new byte[newLen];
+        System.arraycopy(blob.data, blob.offset, tmp, 0, blob.length);
+        blob.data = tmp;
+        pos -= blob.offset;
+        blob.offset = 0;
+        blob.length = pos + realLen;
+      }
+      System.arraycopy(buf, off, blob.data, pos, realLen);
+      pos += realLen;
+    }
+
+    @Override
+    public void write(byte[] buf) throws IOException {
+      write(buf, 0, buf.length);
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/MariaDbClob.java b/src/main/java/org/mariadb/jdbc/MariaDbClob.java
new file mode 100644
index 0000000..a06cd20
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/MariaDbClob.java
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.*;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.StandardCharsets;
+import java.sql.Clob;
+import java.sql.NClob;
+import java.sql.SQLException;
+
+/** MariaDB Clob implementation */
+public class MariaDbClob extends MariaDbBlob implements Clob, NClob, Serializable {
+
+  private static final long serialVersionUID = -3066501059817815286L;
+
+  /**
+   * Creates a Clob with content.
+   *
+   * @param bytes the content for the Clob.
+   */
+  public MariaDbClob(byte[] bytes) {
+    super(bytes);
+  }
+
+  /**
+   * Creates a Clob with content.
+   *
+   * @param bytes the content for the Clob.
+   * @param offset offset
+   * @param length length
+   */
+  public MariaDbClob(byte[] bytes, int offset, int length) {
+    super(bytes, offset, length);
+  }
+
+  /** Creates an empty Clob. */
+  public MariaDbClob() {
+    super();
+  }
+
+  /**
+   * ToString implementation.
+   *
+   * @return string value of blob content.
+   */
+  public String toString() {
+    return new String(data, offset, length, StandardCharsets.UTF_8);
+  }
+
+  /**
+   * Get sub string.
+   *
+   * @param pos position
+   * @param length length of sub string
+   * @return substring
+   * @throws SQLException if pos is less than 1 or length is less than 0
+   */
+  public String getSubString(long pos, int length) throws SQLException {
+
+    if (pos < 1) {
+      throw new SQLException("position must be >= 1");
+    }
+
+    if (length < 0) {
+      throw new SQLException("length must be > 0");
+    }
+
+    String val = toString();
+    return val.substring((int) pos - 1, Math.min((int) pos - 1 + length, val.length()));
+  }
+
+  public Reader getCharacterStream() {
+    return new StringReader(toString());
+  }
+
+  /**
+   * Returns a Reader object that contains a partial Clob value, starting with the character
+   * specified by pos, which is length characters in length.
+   *
+   * @param pos the offset to the first character of the partial value to be retrieved. The first
+   *     character in the Clob is at position 1.
+   * @param length the length in characters of the partial value to be retrieved.
+   * @return Reader through which the partial Clob value can be read.
+   * @throws SQLException if pos is less than 1 or if pos is greater than the number of characters
+   *     in the Clob or if pos + length is greater than the number of characters in the Clob
+   */
+  public Reader getCharacterStream(long pos, long length) throws SQLException {
+    String val = toString();
+    if (val.length() < (int) pos - 1 + length) {
+      throw new SQLException("pos + length is greater than the number of characters in the Clob");
+    }
+    String sub = val.substring((int) pos - 1, (int) pos - 1 + (int) length);
+    return new StringReader(sub);
+  }
+
+  /**
+   * Set character stream.
+   *
+   * @param pos position
+   * @return writer
+   * @throws SQLException if position is invalid
+   */
+  public Writer setCharacterStream(long pos) throws SQLException {
+    int bytePosition = utf8Position((int) pos - 1);
+    OutputStream stream = setBinaryStream(bytePosition + 1);
+    return new OutputStreamWriter(stream, StandardCharsets.UTF_8);
+  }
+
+  public InputStream getAsciiStream() throws SQLException {
+    return getBinaryStream();
+  }
+
+  public long position(String searchStr, long start) {
+    return toString().indexOf(searchStr, (int) start - 1) + 1;
+  }
+
+  public long position(Clob searchStr, long start) {
+    return position(searchStr.toString(), start);
+  }
+
+  /**
+   * Convert character position into byte position in UTF8 byte array.
+   *
+   * @param charPosition charPosition
+   * @return byte position
+   */
+  private int utf8Position(int charPosition) {
+    int pos = offset;
+    for (int i = 0; i < charPosition; i++) {
+      int byteValue = data[pos] & 0xff;
+      if (byteValue < 0x80) {
+        pos += 1;
+      } else if (byteValue < 0xE0) {
+        pos += 2;
+      } else if (byteValue < 0xF0) {
+        pos += 3;
+      } else {
+        pos += 4;
+      }
+    }
+    return pos;
+  }
+
+  /**
+   * Set String.
+   *
+   * @param pos position
+   * @param str string
+   * @return string length
+   * @throws SQLException if UTF-8 conversion failed
+   */
+  public int setString(long pos, String str) throws SQLException {
+    if (str == null) {
+      throw new SQLException("cannot add null string");
+    }
+    if (pos < 0) {
+      throw new SQLException("position must be >= 0");
+    }
+    int bytePosition = utf8Position((int) pos - 1);
+    super.setBytes(bytePosition + 1 - offset, str.getBytes(StandardCharsets.UTF_8));
+    return str.length();
+  }
+
+  public int setString(long pos, String str, int offset, int len) throws SQLException {
+    if (str == null) {
+      throw new SQLException("cannot add null string");
+    }
+
+    if (offset < 0) {
+      throw new SQLException("offset must be >= 0");
+    }
+
+    if (len < 0) {
+      throw new SQLException("len must be > 0");
+    }
+    return setString(pos, str.substring(offset, Math.min(offset + len, str.length())));
+  }
+
+  public OutputStream setAsciiStream(long pos) throws SQLException {
+    return setBinaryStream(utf8Position((int) pos - 1) + 1);
+  }
+
+  /** Return character length of the Clob. Assume UTF8 encoding. */
+  @Override
+  public long length() {
+    // The length of a character string is the number of UTF-16 units (not the number of characters)
+    long len = 0;
+    int pos = offset;
+
+    // set ASCII (<= 127 chars)
+    while (len < length && data[pos] > 0) {
+      len++;
+      pos++;
+    }
+
+    // multi-bytes UTF-8
+    while (pos < offset + length) {
+      byte firstByte = data[pos++];
+      if (firstByte < 0) {
+        if (firstByte >> 5 != -2 || (firstByte & 30) == 0) {
+          if (firstByte >> 4 == -2) {
+            if (pos + 1 < offset + length) {
+              pos += 2;
+              len++;
+            } else {
+              throw new UncheckedIOException("invalid UTF8", new CharacterCodingException());
+            }
+          } else if (firstByte >> 3 != -2) {
+            throw new UncheckedIOException("invalid UTF8", new CharacterCodingException());
+          } else if (pos + 2 < offset + length) {
+            pos += 3;
+            len += 2;
+          } else {
+            // bad truncated UTF8
+            pos += offset + length;
+            len += 1;
+          }
+        } else {
+          pos++;
+          len++;
+        }
+      } else {
+        len++;
+      }
+    }
+    return len;
+  }
+
+  @Override
+  public void truncate(final long truncateLen) {
+
+    // truncate the number of UTF-16 characters
+    // this can result in a bad UTF-8 string if string finish with a
+    // character represented in 2 UTF-16
+    long len = 0;
+    int pos = offset;
+
+    // set ASCII (<= 127 chars)
+    while (len < length && len < truncateLen && data[pos] >= 0) {
+      len++;
+      pos++;
+    }
+
+    // multi-bytes UTF-8
+    while (pos < offset + length && len < truncateLen) {
+      byte firstByte = data[pos++];
+      if (firstByte < 0) {
+        if (firstByte >> 5 != -2 || (firstByte & 30) == 0) {
+          if (firstByte >> 4 == -2) {
+            if (pos + 1 < offset + length) {
+              pos += 2;
+              len++;
+            } else {
+              throw new UncheckedIOException("invalid UTF8", new CharacterCodingException());
+            }
+          } else if (firstByte >> 3 != -2) {
+            throw new UncheckedIOException("invalid UTF8", new CharacterCodingException());
+          } else if (pos + 2 < offset + length) {
+            if (len + 2 <= truncateLen) {
+              pos += 3;
+              len += 2;
+            } else {
+              // truncation will result in bad UTF-8 String
+              pos += 1;
+              len = truncateLen;
+            }
+          } else {
+            throw new UncheckedIOException("invalid UTF8", new CharacterCodingException());
+          }
+        } else {
+          pos++;
+          len++;
+        }
+      } else {
+        len++;
+      }
+    }
+    length = pos - offset;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    MariaDbClob that = (MariaDbClob) o;
+
+    if (length != that.length) return false;
+
+    for (int i = 0; i < length; i++) {
+      if (data[offset + i] != that.data[that.offset + i]) return false;
+    }
+    return true;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/MariaDbDataSource.java b/src/main/java/org/mariadb/jdbc/MariaDbDataSource.java
new file mode 100644
index 0000000..f1060be
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/MariaDbDataSource.java
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.PrintWriter;
+import java.sql.*;
+import java.sql.Connection;
+import java.util.logging.Logger;
+import javax.sql.*;
+
+/** MariaDB basic datasource */
+public class MariaDbDataSource implements DataSource, ConnectionPoolDataSource, XADataSource {
+
+  /** configuration */
+  private Configuration conf = null;
+
+  /** url permitting creating configuration */
+  private String url = null;
+
+  /** username */
+  private String user = null;
+
+  /** password */
+  private String password = null;
+
+  /** connect timeout */
+  private Integer loginTimeout = null;
+
+  /** Basic constructor */
+  public MariaDbDataSource() {}
+
+  /**
+   * Constructor with URL
+   *
+   * @param url connection string
+   * @throws SQLException if url is not supported
+   */
+  public MariaDbDataSource(String url) throws SQLException {
+    if (Configuration.acceptsUrl(url)) {
+      this.url = url;
+    } else {
+      throw new SQLException(String.format("Wrong mariaDB url: %s", url));
+    }
+  }
+
+  /**
+   * Create configuration from url/user/password/loginTimeout
+   *
+   * @throws SQLException if not supported
+   */
+  private void config() throws SQLException {
+    if (url == null) throw new SQLException("url not set");
+    conf = Configuration.parse(url);
+    if (loginTimeout != null) conf.connectTimeout(loginTimeout * 1000);
+    if (user != null || password != null) {
+      conf = conf.clone(user, password);
+    }
+    if (user != null) {
+      user = conf.user();
+    }
+    if (password != null) {
+      password = conf.password();
+    }
+  }
+
+  /**
+   * Attempts to establish a connection with the data source that this {@code DataSource} object
+   * represents.
+   *
+   * @return a connection to the data source
+   * @throws SQLException if a database access error occurs
+   * @throws SQLTimeoutException when the driver has determined that the timeout value specified by
+   *     the {@code setLoginTimeout} method has been exceeded and has at least tried to cancel the
+   *     current database connection attempt
+   */
+  @Override
+  public Connection getConnection() throws SQLException {
+    if (conf == null) config();
+    return Driver.connect(conf);
+  }
+
+  /**
+   * Attempts to establish a connection with the data source that this {@code DataSource} object
+   * represents.
+   *
+   * @param username the database user on whose behalf the connection is being made
+   * @param password the user's password
+   * @return a connection to the data source
+   * @throws SQLException if a database access error occurs
+   * @throws SQLTimeoutException when the driver has determined that the timeout value specified by
+   *     the {@code setLoginTimeout} method has been exceeded and has at least tried to cancel the
+   *     current database connection attempt
+   */
+  @Override
+  public Connection getConnection(String username, String password) throws SQLException {
+    if (conf == null) config();
+    Configuration conf = this.conf.clone(username, password);
+    return Driver.connect(conf);
+  }
+
+  /**
+   * Returns an object that implements the given interface to allow access to non-standard methods,
+   * or standard methods not exposed by the proxy.
+   *
+   * <p>If the receiver implements the interface then the result is the receiver or a proxy for the
+   * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the
+   * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of
+   * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If
+   * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException
+   * </code> is thrown.
+   *
+   * @param iface A Class defining an interface that the result must implement.
+   * @return an object that implements the interface. Maybe a proxy for the actual implementing
+   *     object.
+   * @throws SQLException If no object found that implements the interface
+   */
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("Datasource is not a wrapper for " + iface.getName());
+  }
+
+  /**
+   * Returns true if this either implements the interface argument or is directly or indirectly a
+   * wrapper for an object that does. Returns false otherwise. If this implements the interface then
+   * return true, else if this is a wrapper then return the result of recursively calling <code>
+   * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not
+   * a wrapper, return false. This method should be implemented as a low-cost operation compared to
+   * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>
+   * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same
+   * argument should succeed.
+   *
+   * @param iface a Class defining an interface.
+   * @return true if this implements the interface or directly or indirectly wraps an object that
+   *     does.
+   */
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+
+  /**
+   * Implementation doesn't use logwriter
+   *
+   * @return the log writer for this data source or null if logging is disabled
+   * @see #setLogWriter
+   */
+  @Override
+  public PrintWriter getLogWriter() {
+    return null;
+  }
+
+  /**
+   * Implementation doesn't use logwriter
+   *
+   * @param out the new log writer; to disable logging, set to null
+   * @see #getLogWriter
+   */
+  @Override
+  public void setLogWriter(PrintWriter out) {}
+
+  /**
+   * Gets the maximum time in seconds that this data source can wait while attempting to connect to
+   * a database. A value of zero means that the timeout is the default system timeout if there is
+   * one; otherwise, it means that there is no timeout. When a <code>DataSource</code> object is
+   * created, the login timeout is initially to 30s.
+   *
+   * @return the data source login time limit
+   * @see #setLoginTimeout
+   */
+  @Override
+  public int getLoginTimeout() {
+    if (loginTimeout != null) return loginTimeout;
+    if (conf != null) return conf.connectTimeout() / 1000;
+    return DriverManager.getLoginTimeout() > 0 ? DriverManager.getLoginTimeout() : 30;
+  }
+
+  /**
+   * Sets the maximum time in seconds that this data source will wait while attempting to connect to
+   * a database. A value of zero specifies that the timeout is the default system timeout if there
+   * is one; otherwise, it specifies that there is no timeout. When a <code>DataSource</code> object
+   * is created, the login timeout is initially 30s.
+   *
+   * @param seconds the data source login time limit
+   * @throws SQLException if wrong configuration set
+   * @see #getLoginTimeout
+   */
+  @Override
+  public void setLoginTimeout(int seconds) throws SQLException {
+    loginTimeout = seconds;
+    if (conf != null) config();
+  }
+
+  /**
+   * Not implemented
+   *
+   * @return the parent Logger for this data source
+   */
+  @Override
+  public Logger getParentLogger() {
+    return null;
+  }
+
+  @Override
+  public PooledConnection getPooledConnection() throws SQLException {
+    if (conf == null) config();
+    return new MariaDbPoolConnection(Driver.connect(conf));
+  }
+
+  @Override
+  public PooledConnection getPooledConnection(String username, String password)
+      throws SQLException {
+    if (conf == null) config();
+    Configuration conf = this.conf.clone(username, password);
+    return new MariaDbPoolConnection(Driver.connect(conf));
+  }
+
+  @Override
+  public XAConnection getXAConnection() throws SQLException {
+    if (conf == null) config();
+    return new MariaDbPoolConnection(Driver.connect(conf));
+  }
+
+  @Override
+  public XAConnection getXAConnection(String username, String password) throws SQLException {
+    if (conf == null) config();
+    Configuration conf = this.conf.clone(username, password);
+    return new MariaDbPoolConnection(Driver.connect(conf));
+  }
+
+  /**
+   * Sets the URL for this datasource
+   *
+   * @param url connection string
+   * @throws SQLException if url is not accepted
+   */
+  public void setUrl(String url) throws SQLException {
+    if (Configuration.acceptsUrl(url)) {
+      this.url = url;
+      config();
+    } else {
+      throw new SQLException(String.format("Wrong mariaDB url: %s", url));
+    }
+  }
+
+  /**
+   * Returns the URL for this datasource
+   *
+   * @return the URL for this datasource
+   */
+  public String getUrl() {
+    if (conf == null) return url;
+    return conf.initialUrl();
+  }
+
+  /**
+   * get User
+   *
+   * @return user
+   */
+  public String getUser() {
+    return user;
+  }
+
+  /**
+   * Set user
+   *
+   * @param user user
+   * @throws SQLException if wrong resulting connection string
+   */
+  public void setUser(String user) throws SQLException {
+    this.user = user;
+    if (conf != null) config();
+  }
+
+  /**
+   * Set password
+   *
+   * @param password password
+   * @throws SQLException if wrong configuration
+   */
+  public void setPassword(String password) throws SQLException {
+    this.password = password;
+    if (conf != null) config();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/MariaDbPoolConnection.java b/src/main/java/org/mariadb/jdbc/MariaDbPoolConnection.java
new file mode 100644
index 0000000..340e68c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/MariaDbPoolConnection.java
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import javax.sql.*;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import org.mariadb.jdbc.util.StringUtils;
+
+/** MariaDB pool connection implementation */
+public class MariaDbPoolConnection implements PooledConnection, XAConnection {
+
+  private final Connection connection;
+  private final List<ConnectionEventListener> connectionEventListeners;
+  private final List<StatementEventListener> statementEventListeners;
+
+  /**
+   * Constructor.
+   *
+   * @param connection connection to retrieve connection options
+   */
+  public MariaDbPoolConnection(Connection connection) {
+    this.connection = connection;
+    this.connection.setPoolConnection(this);
+    statementEventListeners = new CopyOnWriteArrayList<>();
+    connectionEventListeners = new CopyOnWriteArrayList<>();
+  }
+
+  @Override
+  public Connection getConnection() {
+    return connection;
+  }
+
+  @Override
+  public void addConnectionEventListener(ConnectionEventListener listener) {
+    connectionEventListeners.add(listener);
+  }
+
+  @Override
+  public void removeConnectionEventListener(ConnectionEventListener listener) {
+    connectionEventListeners.remove(listener);
+  }
+
+  @Override
+  public void addStatementEventListener(StatementEventListener listener) {
+    statementEventListeners.add(listener);
+  }
+
+  @Override
+  public void removeStatementEventListener(StatementEventListener listener) {
+    statementEventListeners.remove(listener);
+  }
+
+  /**
+   * Fire statement close event to registered listeners.
+   *
+   * @param statement closing statement
+   */
+  public void fireStatementClosed(PreparedStatement statement) {
+    StatementEvent event = new StatementEvent(this, statement);
+    for (StatementEventListener listener : statementEventListeners) {
+      listener.statementClosed(event);
+    }
+  }
+
+  /**
+   * Fire statement error event to registered listeners.
+   *
+   * @param statement closing statement
+   * @param returnEx exception
+   */
+  public void fireStatementErrorOccurred(PreparedStatement statement, SQLException returnEx) {
+    StatementEvent event = new StatementEvent(this, statement, returnEx);
+    for (StatementEventListener listener : statementEventListeners) {
+      listener.statementErrorOccurred(event);
+    }
+  }
+
+  /**
+   * Fire connection close event to registered listeners.
+   *
+   * @param event close connection event
+   */
+  public void fireConnectionClosed(ConnectionEvent event) {
+    for (ConnectionEventListener listener : connectionEventListeners) {
+      listener.connectionClosed(event);
+    }
+  }
+
+  /**
+   * Fire connection error event to registered listeners.
+   *
+   * @param returnEx exception
+   */
+  public void fireConnectionErrorOccurred(SQLException returnEx) {
+    ConnectionEvent event = new ConnectionEvent(this, returnEx);
+    for (ConnectionEventListener listener : connectionEventListeners) {
+      listener.connectionErrorOccurred(event);
+    }
+  }
+
+  /**
+   * Close underlying connection
+   *
+   * @throws SQLException if close fails
+   */
+  @Override
+  public void close() throws SQLException {
+    fireConnectionClosed(new ConnectionEvent(this));
+    connection.setPoolConnection(null);
+    connection.close();
+  }
+
+  /**
+   * Create XID string
+   *
+   * @param xid xid value
+   * @return XID string
+   */
+  public static String xidToString(Xid xid) {
+    return "0x"
+        + StringUtils.byteArrayToHexString(xid.getGlobalTransactionId())
+        + ",0x"
+        + StringUtils.byteArrayToHexString(xid.getBranchQualifier())
+        + ",0x"
+        + Integer.toHexString(xid.getFormatId());
+  }
+
+  @Override
+  public XAResource getXAResource() {
+    return new MariaDbXAResource();
+  }
+
+  private class MariaDbXAResource implements XAResource {
+
+    private String flagsToString(int flags) {
+      switch (flags) {
+        case TMJOIN:
+          return "JOIN";
+        case TMONEPHASE:
+          return "ONE PHASE";
+        case TMRESUME:
+          return "RESUME";
+        case TMSUSPEND:
+          return "SUSPEND";
+        default:
+          return "";
+      }
+    }
+
+    private XAException mapXaException(SQLException sqle) {
+      int xaErrorCode;
+
+      switch (sqle.getErrorCode()) {
+        case 1397:
+          xaErrorCode = XAException.XAER_NOTA;
+          break;
+        case 1398:
+          xaErrorCode = XAException.XAER_INVAL;
+          break;
+        case 1399:
+          xaErrorCode = XAException.XAER_RMFAIL;
+          break;
+        case 1400:
+          xaErrorCode = XAException.XAER_OUTSIDE;
+          break;
+        case 1401:
+          xaErrorCode = XAException.XAER_RMERR;
+          break;
+        case 1402:
+          xaErrorCode = XAException.XA_RBROLLBACK;
+          break;
+        default:
+          xaErrorCode = 0;
+          break;
+      }
+      XAException xaException;
+      if (xaErrorCode != 0) {
+        xaException = new XAException(xaErrorCode);
+      } else {
+        xaException = new XAException(sqle.getMessage());
+      }
+      xaException.initCause(sqle);
+      return xaException;
+    }
+
+    private void execute(String command) throws XAException {
+      try {
+        connection.createStatement().execute(command);
+      } catch (SQLException sqle) {
+        throw mapXaException(sqle);
+      }
+    }
+
+    @Override
+    public void commit(Xid xid, boolean onePhase) throws XAException {
+      execute("XA COMMIT " + xidToString(xid) + ((onePhase) ? " ONE PHASE" : ""));
+    }
+
+    @Override
+    public void end(Xid xid, int flags) throws XAException {
+      if (flags != TMSUCCESS && flags != TMSUSPEND && flags != TMFAIL) {
+        throw new XAException(XAException.XAER_INVAL);
+      }
+
+      execute("XA END " + xidToString(xid) + " " + flagsToString(flags));
+    }
+
+    @Override
+    public void forget(Xid xid) {
+      // Not implemented by the server
+    }
+
+    @Override
+    public int getTransactionTimeout() {
+      // not implemented
+      return 0;
+    }
+
+    public Configuration getConf() {
+      return connection.getContext().getConf();
+    }
+
+    @Override
+    public boolean isSameRM(XAResource xaResource) {
+      if (xaResource instanceof MariaDbXAResource) {
+        MariaDbXAResource other = (MariaDbXAResource) xaResource;
+        return other.getConf().equals(this.getConf());
+      }
+      return false;
+    }
+
+    @Override
+    public int prepare(Xid xid) throws XAException {
+      execute("XA PREPARE " + xidToString(xid));
+      return XA_OK;
+    }
+
+    @Override
+    public Xid[] recover(int flags) throws XAException {
+      if (((flags & TMSTARTRSCAN) == 0) && ((flags & TMENDRSCAN) == 0) && (flags != TMNOFLAGS)) {
+        throw new XAException(XAException.XAER_INVAL);
+      }
+
+      if ((flags & TMSTARTRSCAN) == 0) {
+        return new MariaDbXid[0];
+      }
+
+      try {
+        ResultSet rs = connection.createStatement().executeQuery("XA RECOVER");
+        ArrayList<MariaDbXid> xidList = new ArrayList<>();
+
+        while (rs.next()) {
+          int formatId = rs.getInt(1);
+          int len1 = rs.getInt(2);
+          int len2 = rs.getInt(3);
+          byte[] arr = rs.getBytes(4);
+
+          byte[] globalTransactionId = new byte[len1];
+          byte[] branchQualifier = new byte[len2];
+          System.arraycopy(arr, 0, globalTransactionId, 0, len1);
+          System.arraycopy(arr, len1, branchQualifier, 0, len2);
+          xidList.add(new MariaDbXid(formatId, globalTransactionId, branchQualifier));
+        }
+        Xid[] xids = new Xid[xidList.size()];
+        xidList.toArray(xids);
+        return xids;
+      } catch (SQLException sqle) {
+        throw mapXaException(sqle);
+      }
+    }
+
+    @Override
+    public void rollback(Xid xid) throws XAException {
+      execute("XA ROLLBACK " + xidToString(xid));
+    }
+
+    @Override
+    public boolean setTransactionTimeout(int i) {
+      return false;
+    }
+
+    @Override
+    public void start(Xid xid, int flags) throws XAException {
+      if (flags != TMJOIN && flags != TMRESUME && flags != TMNOFLAGS) {
+        throw new XAException(XAException.XAER_INVAL);
+      }
+      execute("XA START " + xidToString(xid) + " " + flagsToString(flags));
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/MariaDbPoolDataSource.java b/src/main/java/org/mariadb/jdbc/MariaDbPoolDataSource.java
new file mode 100644
index 0000000..326a82f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/MariaDbPoolDataSource.java
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.io.Closeable;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.SQLTimeoutException;
+import java.util.List;
+import java.util.logging.Logger;
+import javax.sql.*;
+import org.mariadb.jdbc.pool.Pool;
+import org.mariadb.jdbc.pool.Pools;
+
+/** MariaDB pool datasource. This use mariadb internal pool. */
+public class MariaDbPoolDataSource
+    implements DataSource, ConnectionPoolDataSource, XADataSource, Closeable, AutoCloseable {
+
+  private Pool pool;
+  private Configuration conf = null;
+  private String url = null;
+  private String user = null;
+  private String password = null;
+  private Integer loginTimeout = null;
+
+  /** Constructor */
+  public MariaDbPoolDataSource() {}
+
+  /**
+   * Constructor with url
+   *
+   * @param url connection string
+   * @throws SQLException if configuration fails
+   */
+  public MariaDbPoolDataSource(String url) throws SQLException {
+    if (Configuration.acceptsUrl(url)) {
+      this.url = url;
+      conf = Configuration.parse(url);
+      pool = Pools.retrievePool(conf);
+    } else {
+      throw new SQLException(String.format("Wrong mariaDB url: %s", url));
+    }
+  }
+
+  private void config() throws SQLException {
+    if (url == null) throw new SQLException("url not set");
+    conf = Configuration.parse(url);
+    if (loginTimeout != null) conf.connectTimeout(loginTimeout * 1000);
+    if (user != null || password != null) {
+      conf = conf.clone(user, password);
+    }
+    if (user != null) {
+      user = conf.user();
+    }
+    if (password != null) {
+      password = conf.password();
+    }
+
+    pool = Pools.retrievePool(conf);
+  }
+
+  /**
+   * Attempts to establish a connection with the data source that this {@code DataSource} object
+   * represents.
+   *
+   * @return a connection to the data source
+   * @throws SQLException if a database access error occurs
+   * @throws SQLTimeoutException when the driver has determined that the timeout value specified by
+   *     the {@code setLoginTimeout} method has been exceeded and has at least tried to cancel the
+   *     current database connection attempt
+   */
+  @Override
+  public Connection getConnection() throws SQLException {
+    if (conf == null) config();
+    return pool.getPoolConnection().getConnection();
+  }
+
+  /**
+   * Attempts to establish a connection with the data source that this {@code DataSource} object
+   * represents.
+   *
+   * @param username the database user on whose behalf the connection is being made
+   * @param password the user's password
+   * @return a connection to the data source
+   * @throws SQLException if a database access error occurs
+   * @throws SQLTimeoutException when the driver has determined that the timeout value specified by
+   *     the {@code setLoginTimeout} method has been exceeded and has at least tried to cancel the
+   *     current database connection attempt
+   */
+  @Override
+  public Connection getConnection(String username, String password) throws SQLException {
+    if (conf == null) config();
+    return pool.getPoolConnection(username, password).getConnection();
+  }
+
+  /**
+   * Returns an object that implements the given interface to allow access to non-standard methods,
+   * or standard methods not exposed by the proxy.
+   *
+   * <p>If the receiver implements the interface then the result is the receiver or a proxy for the
+   * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the
+   * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of
+   * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If
+   * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException
+   * </code> is thrown.
+   *
+   * @param iface A Class defining an interface that the result must implement.
+   * @return an object that implements the interface. Maybe a proxy for the actual implementing
+   *     object.
+   * @throws SQLException If no object found that implements the interface
+   */
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("Datasource is not a wrapper for " + iface.getName());
+  }
+
+  /**
+   * Returns true if this either implements the interface argument or is directly or indirectly a
+   * wrapper for an object that does. Returns false otherwise. If this implements the interface then
+   * return true, else if this is a wrapper then return the result of recursively calling <code>
+   * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not
+   * a wrapper, return false. This method should be implemented as a low-cost operation compared to
+   * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>
+   * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same
+   * argument should succeed.
+   *
+   * @param iface a Class defining an interface.
+   * @return true if this implements the interface or directly or indirectly wraps an object that
+   *     does.
+   */
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+
+  /**
+   * Implementation doesn't use logwriter
+   *
+   * @return the log writer for this data source or null if logging is disabled
+   * @see #setLogWriter
+   */
+  @Override
+  public PrintWriter getLogWriter() {
+    return null;
+  }
+
+  /**
+   * Implementation doesn't use logwriter
+   *
+   * @param out the new log writer; to disable logging, set to null
+   * @see #getLogWriter
+   */
+  @Override
+  public void setLogWriter(PrintWriter out) {}
+
+  /**
+   * Gets the maximum time in seconds that this data source can wait while attempting to connect to
+   * a database. A value of zero means that the timeout is the default system timeout if there is
+   * one; otherwise, it means that there is no timeout. When a <code>DataSource</code> object is
+   * created, the login timeout is initially to 30s.
+   *
+   * @return the data source login time limit
+   * @see #setLoginTimeout
+   */
+  @Override
+  public int getLoginTimeout() {
+    if (loginTimeout != null) return loginTimeout;
+    if (conf != null) return conf.connectTimeout() / 1000;
+    return DriverManager.getLoginTimeout() > 0 ? DriverManager.getLoginTimeout() : 30;
+  }
+
+  /**
+   * Sets the maximum time in seconds that this data source will wait while attempting to connect to
+   * a database. A value of zero specifies that the timeout is the default system timeout if there
+   * is one; otherwise, it specifies that there is no timeout. When a <code>DataSource</code> object
+   * is created, the login timeout is initially 30s.
+   *
+   * @param seconds the data source login time limit
+   * @throws SQLException if wrong configuration set
+   * @see #getLoginTimeout
+   */
+  @Override
+  public void setLoginTimeout(int seconds) throws SQLException {
+    loginTimeout = seconds;
+    if (conf != null) config();
+  }
+
+  /**
+   * Not implemented
+   *
+   * @return the parent Logger for this data source
+   */
+  @Override
+  public Logger getParentLogger() {
+    return null;
+  }
+
+  @Override
+  public PooledConnection getPooledConnection() throws SQLException {
+    if (conf == null) config();
+    return pool.getPoolConnection();
+  }
+
+  @Override
+  public PooledConnection getPooledConnection(String username, String password)
+      throws SQLException {
+    if (conf == null) config();
+    return pool.getPoolConnection(username, password);
+  }
+
+  @Override
+  public XAConnection getXAConnection() throws SQLException {
+    if (conf == null) config();
+    return pool.getPoolConnection();
+  }
+
+  @Override
+  public XAConnection getXAConnection(String username, String password) throws SQLException {
+    if (conf == null) config();
+    return pool.getPoolConnection(username, password);
+  }
+
+  /**
+   * Sets the URL for this datasource
+   *
+   * @param url connection string
+   * @throws SQLException if url is not accepted
+   */
+  public void setUrl(String url) throws SQLException {
+    if (Configuration.acceptsUrl(url)) {
+      this.url = url;
+      config();
+    } else {
+      throw new SQLException(String.format("Wrong mariaDB url: %s", url));
+    }
+  }
+
+  /**
+   * Returns the URL for this datasource
+   *
+   * @return the URL for this datasource
+   */
+  public String getUrl() {
+    if (conf == null) return url;
+    return conf.initialUrl();
+  }
+
+  /**
+   * return user
+   *
+   * @return user
+   */
+  public String getUser() {
+    return user;
+  }
+
+  /**
+   * Set user
+   *
+   * @param user user
+   * @throws SQLException if configuration fails
+   */
+  public void setUser(String user) throws SQLException {
+    this.user = user;
+    if (conf != null) config();
+  }
+
+  /**
+   * set password
+   *
+   * @param password password
+   * @throws SQLException if configuration fails
+   */
+  public void setPassword(String password) throws SQLException {
+    this.password = password;
+    if (conf != null) config();
+  }
+
+  /** Close datasource. */
+  public void close() {
+    pool.close();
+  }
+
+  /**
+   * get pool name
+   *
+   * @return pool name
+   */
+  public String getPoolName() {
+    return (pool != null) ? pool.getPoolTag() : null;
+  }
+
+  /**
+   * Get current idle threads. !! For testing purpose only !!
+   *
+   * @return current thread id's
+   */
+  public List<Long> testGetConnectionIdleThreadIds() {
+    return (pool != null) ? pool.testGetConnectionIdleThreadIds() : null;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/MariaDbXid.java b/src/main/java/org/mariadb/jdbc/MariaDbXid.java
new file mode 100644
index 0000000..3ba44e5
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/MariaDbXid.java
@@ -0,0 +1,77 @@
+package org.mariadb.jdbc;
+
+import java.util.Arrays;
+import java.util.Objects;
+import javax.transaction.xa.Xid;
+
+/** MariaDB XID implementation */
+public class MariaDbXid implements Xid {
+
+  private final int formatId;
+  private final byte[] globalTransactionId;
+  private final byte[] branchQualifier;
+
+  /**
+   * Global transaction identifier.
+   *
+   * @param formatId the format identifier part of the XID.
+   * @param globalTransactionId the global transaction identifier part of XID as an array of bytes.
+   * @param branchQualifier the transaction branch identifier part of XID as an array of bytes.
+   */
+  public MariaDbXid(int formatId, byte[] globalTransactionId, byte[] branchQualifier) {
+    this.formatId = formatId;
+    this.globalTransactionId = globalTransactionId;
+    this.branchQualifier = branchQualifier;
+  }
+
+  /**
+   * Equal implementation.
+   *
+   * @param obj object to compare
+   * @return true if object is MariaDbXi and as same parameters
+   */
+  public boolean equals(Object obj) {
+    if (obj instanceof Xid) {
+      Xid other = (Xid) obj;
+      return formatId == other.getFormatId()
+          && Arrays.equals(globalTransactionId, other.getGlobalTransactionId())
+          && Arrays.equals(branchQualifier, other.getBranchQualifier());
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = Objects.hash(formatId);
+    result = 31 * result + Arrays.hashCode(globalTransactionId);
+    result = 31 * result + Arrays.hashCode(branchQualifier);
+    return result;
+  }
+
+  /**
+   * Get format id from XID
+   *
+   * @return format id
+   */
+  public int getFormatId() {
+    return formatId;
+  }
+
+  /**
+   * Get global transaction id from XID
+   *
+   * @return global transaction id
+   */
+  public byte[] getGlobalTransactionId() {
+    return globalTransactionId;
+  }
+
+  /**
+   * Get branch qualifier from XID
+   *
+   * @return branch qualifier
+   */
+  public byte[] getBranchQualifier() {
+    return branchQualifier;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/ParameterMetaData.java b/src/main/java/org/mariadb/jdbc/ParameterMetaData.java
new file mode 100644
index 0000000..019e672
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/ParameterMetaData.java
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.export.ExceptionFactory;
+
+/** Parameter metadata */
+public class ParameterMetaData implements java.sql.ParameterMetaData {
+
+  private final ColumnDecoder[] params;
+  private final ExceptionFactory exceptionFactory;
+
+  /**
+   * Constructor
+   *
+   * @param exceptionFactory exception factory
+   * @param params columns metadata
+   */
+  protected ParameterMetaData(ExceptionFactory exceptionFactory, ColumnDecoder[] params) {
+    this.params = params;
+    this.exceptionFactory = exceptionFactory;
+  }
+
+  /**
+   * Retrieves the number of parameters in the <code>PreparedStatement</code> object for which this
+   * <code>ParameterMetaData</code> object contains information.
+   *
+   * @return the number of parameters
+   */
+  @Override
+  public int getParameterCount() {
+    return params.length;
+  }
+
+  private void checkIndex(int index) throws SQLException {
+    if (index < 1 || index > params.length) {
+      throw new SQLException(
+          String.format(
+              "Wrong index position. Is %s but must be in 1-%s range", index, params.length));
+    }
+  }
+
+  /**
+   * Retrieves whether null values are allowed in the designated parameter.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return the nullability status of the given parameter; one of <code>
+   *     ParameterMetaData.parameterNoNulls</code>, <code>ParameterMetaData.parameterNullable</code>
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public int isNullable(int idx) throws SQLException {
+    checkIndex(idx);
+    return java.sql.ParameterMetaData.parameterNullable;
+  }
+
+  /**
+   * Retrieves whether values for the designated parameter can be signed numbers.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public boolean isSigned(int idx) throws SQLException {
+    checkIndex(idx);
+    return params[idx - 1].isSigned();
+  }
+
+  /**
+   * Retrieves the designated parameter's specified column size.
+   *
+   * <p>The returned value represents the maximum column size for the given parameter. For numeric
+   * data, this is the maximum precision. For character data, this is the length in characters. For
+   * datetime datatypes, this is the length in characters of the String representation (assuming the
+   * maximum allowed precision of the fractional seconds component). For binary data, this is the
+   * length in bytes. For the ROWID datatype, this is the length in bytes. 0 is returned for data
+   * types where the column size is not applicable.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return precision
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public int getPrecision(int idx) throws SQLException {
+    checkIndex(idx);
+    return params[idx - 1].getPrecision();
+  }
+
+  /**
+   * Retrieves the designated parameter's number of digits to right of the decimal point. 0 is
+   * returned for data types where the scale is not applicable. Parameter type are not sent by
+   * server. See * https://jira.mariadb.org/browse/CONJ-568 and
+   * https://jira.mariadb.org/browse/MDEV-15031
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return scale
+   * @throws SQLException if a database access error occurs
+   */
+  @Override
+  public int getScale(int idx) throws SQLException {
+    checkIndex(idx);
+    return params[idx - 1].getDecimals();
+  }
+
+  /**
+   * Retrieves the designated parameter's SQL type. Parameter type are not sent by server. See
+   * https://jira.mariadb.org/browse/CONJ-568 and https://jira.mariadb.org/browse/MDEV-15031
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return SQL types from <code>java.sql.Types</code>
+   * @throws SQLException because not supported
+   */
+  @Override
+  public int getParameterType(int idx) throws SQLException {
+    checkIndex(idx);
+    throw exceptionFactory.create("Getting parameter type metadata are not supported", "0A000", -1);
+  }
+
+  /**
+   * Retrieves the designated parameter's database-specific type name.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return type the name used by the database. If the parameter type is a user-defined type, then
+   *     a fully-qualified type name is returned.
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public String getParameterTypeName(int idx) throws SQLException {
+    checkIndex(idx);
+    // https://jira.mariadb.org/browse/XPT-279 Xpand can return wrong datatype for parameters
+    DataType type = params[idx - 1].getType();
+    return type == null ? null : type.name();
+  }
+
+  /**
+   * Retrieves the fully-qualified name of the Java class whose instances should be passed to the
+   * method <code>PreparedStatement.setObject</code>.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return the fully-qualified name of the class in the Java programming language that would be
+   *     used by the method <code>PreparedStatement.setObject</code> to set the value in the
+   *     specified parameter. This is the class name used for custom mapping.
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public String getParameterClassName(int idx) throws SQLException {
+    checkIndex(idx);
+    throw exceptionFactory.create("Unknown parameter metadata class name", "0A000");
+  }
+
+  /**
+   * Retrieves the designated parameter's mode.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return mode of the parameter; one of <code>ParameterMetaData.parameterModeIn</code>, <code>
+   *     ParameterMetaData.parameterModeOut</code>, or <code>ParameterMetaData.parameterModeInOut
+   *     </code> <code>ParameterMetaData.parameterModeUnknown</code>.
+   */
+  @Override
+  public int getParameterMode(int idx) throws SQLException {
+    checkIndex(idx);
+    return java.sql.ParameterMetaData.parameterModeIn;
+  }
+
+  /**
+   * Returns an object that implements the given interface to allow access to non-standard methods,
+   * or standard methods not exposed by the proxy.
+   *
+   * <p>If the receiver implements the interface then the result is the receiver or a proxy for the
+   * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the
+   * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of
+   * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If
+   * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException
+   * </code> is thrown.
+   *
+   * @param iface A Class defining an interface that the result must implement.
+   * @return an object that implements the interface. Maybe a proxy for the actual implementing
+   *     object.
+   * @throws SQLException If no object found that implements the interface
+   */
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
+  }
+
+  /**
+   * Returns true if this either implements the interface argument or is directly or indirectly a
+   * wrapper for an object that does. Returns false otherwise. If this implements the interface then
+   * return true, else if this is a wrapper then return the result of recursively calling <code>
+   * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not
+   * a wrapper, return false. This method should be implemented as a low-cost operation compared to
+   * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>
+   * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same
+   * argument should succeed.
+   *
+   * @param iface a Class defining an interface.
+   * @return true if this implements the interface or directly or indirectly wraps an object that
+   *     does.
+   */
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/ProcedureStatement.java b/src/main/java/org/mariadb/jdbc/ProcedureStatement.java
new file mode 100644
index 0000000..b917ceb
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/ProcedureStatement.java
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.result.Result;
+
+/** Procedure callable statement */
+public class ProcedureStatement extends BaseCallableStatement implements CallableStatement {
+
+  /**
+   * Constructor
+   *
+   * @param con connection
+   * @param sql sql
+   * @param databaseName database
+   * @param procedureName procedure
+   * @param lock thread locker
+   * @param canUseServerTimeout can use server timeout
+   * @param canUseServerMaxRows can use server max rows
+   * @param canCachePrepStmts can cache server prepared result
+   * @param resultSetType result-set type
+   * @param resultSetConcurrency concurrency
+   * @throws SQLException if any exception occurs
+   */
+  public ProcedureStatement(
+      Connection con,
+      String sql,
+      String databaseName,
+      String procedureName,
+      ReentrantLock lock,
+      boolean canUseServerTimeout,
+      boolean canUseServerMaxRows,
+      boolean canCachePrepStmts,
+      int resultSetType,
+      int resultSetConcurrency)
+      throws SQLException {
+    super(
+        sql,
+        con,
+        lock,
+        databaseName,
+        procedureName,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        canCachePrepStmts,
+        resultSetType,
+        resultSetConcurrency,
+        0);
+  }
+
+  @Override
+  public boolean isFunction() {
+    return false;
+  }
+
+  @Override
+  protected void handleParameterOutput() throws SQLException {
+    // output result-set is the last result-set
+    // or in case finishing with an OK_PACKET, just the one before
+    for (int i = 1; i <= Math.min(this.results.size(), 2); i++) {
+      Completion compl = this.results.get(this.results.size() - i);
+      if (compl instanceof Result && (((Result) compl).isOutputParameter())) {
+        outputResultFromRes(i);
+      }
+    }
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("ProcedureStatement{sql:'" + sql + "'");
+    sb.append(", parameters:[");
+    for (int i = 0; i < parameters.size(); i++) {
+      org.mariadb.jdbc.client.util.Parameter param = parameters.get(i);
+      if (outputParameters.contains(i + 1)) sb.append("<OUT>");
+      if (param == null) {
+        sb.append("null");
+      } else {
+        sb.append(param.bestEffortStringValue(con.getContext()));
+      }
+      if (i != parameters.size() - 1) {
+        sb.append(",");
+      }
+    }
+    sb.append("]}");
+    return sb.toString();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/ServerPreparedStatement.java b/src/main/java/org/mariadb/jdbc/ServerPreparedStatement.java
new file mode 100644
index 0000000..7dc982d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/ServerPreparedStatement.java
@@ -0,0 +1,695 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import static org.mariadb.jdbc.util.constants.Capabilities.*;
+
+import java.sql.*;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Pattern;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.client.result.Result;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.client.BulkExecutePacket;
+import org.mariadb.jdbc.message.client.ExecutePacket;
+import org.mariadb.jdbc.message.client.PrepareExecutePacket;
+import org.mariadb.jdbc.message.client.PreparePacket;
+import org.mariadb.jdbc.message.server.OkPacket;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+import org.mariadb.jdbc.util.ParameterList;
+
+/**
+ * Server prepare statement. command will generate COM_STMT_PREPARE + COM_STMT_EXECUTE (+
+ * COM_STMT_CLOSE)
+ */
+public class ServerPreparedStatement extends BasePreparedStatement {
+  private static final Pattern PREPARABLE_STATEMENT_PATTERN =
+      Pattern.compile("^(SELECT|UPDATE|INSERT|DELETE|REPLACE|DO|CALL)", Pattern.CASE_INSENSITIVE);
+  private final boolean canCachePrepStmts;
+  /**
+   * Server prepare statement constructor
+   *
+   * @param sql command
+   * @param con connection
+   * @param lock thread safe lock
+   * @param canUseServerTimeout can server use timeout
+   * @param canUseServerMaxRows can server use max rows
+   * @param canCachePrepStmts can server cache prepared statement
+   * @param autoGeneratedKeys must command return automatically generated keys
+   * @param resultSetType resultset type
+   * @param resultSetConcurrency resultset concurrency
+   * @param defaultFetchSize default fetch size
+   * @throws SQLException if prepare fails
+   */
+  public ServerPreparedStatement(
+      String sql,
+      Connection con,
+      ReentrantLock lock,
+      boolean canUseServerTimeout,
+      boolean canUseServerMaxRows,
+      boolean canCachePrepStmts,
+      int autoGeneratedKeys,
+      int resultSetType,
+      int resultSetConcurrency,
+      int defaultFetchSize)
+      throws SQLException {
+    super(
+        sql,
+        con,
+        lock,
+        canUseServerTimeout,
+        canUseServerMaxRows,
+        autoGeneratedKeys,
+        resultSetType,
+        resultSetConcurrency,
+        defaultFetchSize);
+    this.canCachePrepStmts = canCachePrepStmts;
+    prepareResult = canCachePrepStmts ? con.getContext().getPrepareCache().get(sql, this) : null;
+    if (prepareResult == null && !PREPARABLE_STATEMENT_PATTERN.matcher(sql).find()) {
+      con.getClient().execute(new PreparePacket(sql), this, true);
+    }
+    parameters = new ParameterList();
+  }
+
+  /**
+   * Execute command with parameters
+   *
+   * @throws SQLException if any error occurs
+   */
+  protected void executeInternal() throws SQLException {
+    checkNotClosed();
+    validParameters();
+    lock.lock();
+    String cmd = escapeTimeout(sql);
+    if (prepareResult == null)
+      if (canCachePrepStmts) prepareResult = con.getContext().getPrepareCache().get(cmd, this);
+    try {
+      if (prepareResult == null && con.getContext().permitPipeline()) {
+        executePipeline(cmd);
+      } else {
+        executeStandard(cmd);
+      }
+    } finally {
+      localInfileInputStream = null;
+      lock.unlock();
+    }
+  }
+
+  /**
+   * Send COM_STMT_PREPARE + COM_STMT_EXECUTE, then read for the 2 answers
+   *
+   * @param cmd command
+   * @throws SQLException if IOException / Command error
+   */
+  private void executePipeline(String cmd) throws SQLException {
+    // server is 10.2+, permitting to execute last prepare with (-1) statement id.
+    // Server send prepare, followed by execute, in one exchange.
+    try {
+      List<Completion> res =
+          con.getClient()
+              .execute(
+                  new PrepareExecutePacket(cmd, parameters, this, localInfileInputStream),
+                  this,
+                  fetchSize,
+                  maxRows,
+                  resultSetConcurrency,
+                  resultSetType,
+                  closeOnCompletion,
+                  false);
+      results = res.subList(1, res.size());
+    } catch (SQLException ex) {
+      results = null;
+      throw ex;
+    }
+  }
+
+  private void executeStandard(String cmd) throws SQLException {
+    // send COM_STMT_PREPARE
+    if (prepareResult == null) {
+      if (canCachePrepStmts) prepareResult = con.getContext().getPrepareCache().get(cmd, this);
+      if (prepareResult == null) {
+        con.getClient().execute(new PreparePacket(cmd), this, true);
+      }
+    }
+    validParameters();
+    // send COM_STMT_EXECUTE
+    ExecutePacket execute =
+        new ExecutePacket(prepareResult, parameters, cmd, this, localInfileInputStream);
+    results =
+        con.getClient()
+            .execute(
+                execute,
+                this,
+                fetchSize,
+                maxRows,
+                resultSetConcurrency,
+                resultSetType,
+                closeOnCompletion,
+                false);
+  }
+
+  private void executeInternalPreparedBatch() throws SQLException {
+    checkNotClosed();
+    String cmd = escapeTimeout(sql);
+    if (batchParameters.size() > 1 && con.getContext().hasServerCapability(STMT_BULK_OPERATIONS)) {
+
+      // ensure pipelining is possible (no LOAD DATA/XML INFILE commands)
+      boolean possibleLoadLocal = con.getContext().hasClientCapability(LOCAL_FILES);
+      if (possibleLoadLocal) {
+        String sqlUpper = sql.toUpperCase(Locale.ROOT);
+        possibleLoadLocal =
+            sqlUpper.contains(" LOCAL ")
+                && sqlUpper.contains("LOAD")
+                && sqlUpper.contains(" INFILE");
+      }
+
+      if (!possibleLoadLocal) {
+        if (con.getContext().getConf().useBulkStmts()
+            && autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS) {
+          executeBatchBulk(cmd);
+        } else {
+          executeBatchPipeline(cmd);
+        }
+        return;
+      }
+    }
+    executeBatchStandard(cmd);
+  }
+
+  /**
+   * Send COM_STMT_PREPARE + X * COM_STMT_BULK_EXECUTE, then read for the all answers
+   *
+   * @param cmd command
+   * @throws SQLException if IOException / Command error
+   */
+  private void executeBatchBulk(String cmd) throws SQLException {
+    List<Completion> res;
+    if (prepareResult == null && canCachePrepStmts)
+      prepareResult = con.getContext().getPrepareCache().get(cmd, this);
+    try {
+      if (prepareResult == null) {
+        ClientMessage[] packets;
+        packets =
+            new ClientMessage[] {
+              new PreparePacket(cmd), new BulkExecutePacket(null, batchParameters, cmd, this)
+            };
+        res =
+            con.getClient()
+                .executePipeline(
+                    packets,
+                    this,
+                    0,
+                    maxRows,
+                    ResultSet.CONCUR_READ_ONLY,
+                    ResultSet.TYPE_FORWARD_ONLY,
+                    closeOnCompletion,
+                    false);
+
+        // in case of failover, prepare is done in failover, skipping prepare result
+        if (res.get(0) instanceof PrepareResultPacket) {
+          results = res.subList(1, res.size());
+        } else {
+          results = res;
+        }
+      } else {
+        results =
+            con.getClient()
+                .execute(
+                    new BulkExecutePacket(prepareResult, batchParameters, cmd, this),
+                    this,
+                    0,
+                    maxRows,
+                    ResultSet.CONCUR_READ_ONLY,
+                    ResultSet.TYPE_FORWARD_ONLY,
+                    closeOnCompletion,
+                    false);
+      }
+
+    } catch (SQLException bue) {
+      results = null;
+      throw exceptionFactory()
+          .createBatchUpdate(Collections.emptyList(), batchParameters.size(), bue);
+    }
+  }
+
+  /**
+   * Send COM_STMT_PREPARE + X * COM_STMT_EXECUTE, then read for the all answers
+   *
+   * @param cmd command
+   * @throws SQLException if Command error
+   */
+  private void executeBatchPipeline(String cmd) throws SQLException {
+    if (prepareResult == null && canCachePrepStmts)
+      prepareResult = con.getContext().getPrepareCache().get(cmd, this);
+    // server is 10.2+, permitting to execute last prepare with (-1) statement id.
+    // Server send prepare, followed by execute, in one exchange.
+    int maxCmd = 250;
+    List<Completion> res = new ArrayList<>();
+    try {
+      int index = 0;
+      if (prepareResult == null) {
+        res.addAll(executeBunchPrepare(cmd, index, maxCmd));
+        index += maxCmd;
+      }
+      while (index < batchParameters.size()) {
+        res.addAll(executeBunch(cmd, index, maxCmd));
+        index += maxCmd;
+      }
+      results = res;
+
+    } catch (SQLException bue) {
+      results = null;
+      throw exceptionFactory().createBatchUpdate(res, batchParameters.size(), bue);
+    }
+  }
+
+  private List<Completion> executeBunch(String cmd, int index, int maxCmd) throws SQLException {
+    int maxCmdToSend = Math.min(batchParameters.size() - index, maxCmd);
+    ClientMessage[] packets = new ClientMessage[maxCmdToSend];
+    for (int i = index; i < index + maxCmdToSend; i++) {
+      packets[i - index] =
+          new ExecutePacket(
+              prepareResult, batchParameters.get(i), cmd, this, localInfileInputStream);
+    }
+    return con.getClient()
+        .executePipeline(
+            packets,
+            this,
+            0,
+            maxRows,
+            ResultSet.CONCUR_READ_ONLY,
+            ResultSet.TYPE_FORWARD_ONLY,
+            closeOnCompletion,
+            false);
+  }
+
+  private List<Completion> executeBunchPrepare(String cmd, int index, int maxCmd)
+      throws SQLException {
+    int maxCmdToSend = Math.min(batchParameters.size() - index, maxCmd);
+    ClientMessage[] packets = new ClientMessage[maxCmdToSend + 1];
+    packets[0] = new PreparePacket(cmd);
+    for (int i = index; i < index + maxCmdToSend; i++) {
+      packets[i + 1 - index] =
+          new ExecutePacket(null, batchParameters.get(i), cmd, this, localInfileInputStream);
+    }
+    List<Completion> res =
+        con.getClient()
+            .executePipeline(
+                packets,
+                this,
+                0,
+                maxRows,
+                ResultSet.CONCUR_READ_ONLY,
+                ResultSet.TYPE_FORWARD_ONLY,
+                closeOnCompletion,
+                false);
+    // in case of failover, prepare is done in failover, skipping prepare result
+    if (res.get(0) instanceof PrepareResultPacket) {
+      return res.subList(1, res.size());
+    } else {
+      return res;
+    }
+  }
+
+  /**
+   * Send COM_STMT_PREPARE + read answer, then Send a COM_STMT_EXECUTE + read answer * n time
+   *
+   * @param cmd command
+   * @throws SQLException if IOException / Command error
+   */
+  private void executeBatchStandard(String cmd) throws SQLException {
+    // send COM_STMT_PREPARE
+    List<Completion> tmpResults = new ArrayList<>();
+    SQLException error = null;
+    for (Parameters batchParameter : batchParameters) {
+      // prepare is in loop, because if connection fail, prepare is reset, and need to be re
+      // prepared
+      if (prepareResult == null) {
+        if (canCachePrepStmts) prepareResult = con.getContext().getPrepareCache().get(cmd, this);
+        if (prepareResult == null) {
+          con.getClient().execute(new PreparePacket(cmd), this, false);
+        }
+      }
+      try {
+        ExecutePacket execute =
+            new ExecutePacket(prepareResult, batchParameter, cmd, this, localInfileInputStream);
+        tmpResults.addAll(con.getClient().execute(execute, this, false));
+      } catch (SQLException e) {
+        if (error == null) error = e;
+      }
+    }
+
+    if (error != null) {
+      throw exceptionFactory().createBatchUpdate(tmpResults, batchParameters.size(), error);
+    }
+    this.results = tmpResults;
+  }
+
+  /**
+   * Executes the SQL statement in this <code>PreparedStatement</code> object, which may be any kind
+   * of SQL statement. Some prepared statements return multiple results; the <code>execute</code>
+   * method handles these complex statements as well as the simpler form of statements handled by
+   * the methods <code>executeQuery</code> and <code>executeUpdate</code>.
+   *
+   * <p>The <code>execute</code> method returns a <code>boolean</code> to indicate the form of the
+   * first result. You must call either the method <code>getResultSet</code> or <code>getUpdateCount
+   * </code> to retrieve the result; you must call <code>getMoreResults</code> to move to any
+   * subsequent result(s).
+   *
+   * @return <code>true</code> if the first result is a <code>ResultSet</code> object; <code>false
+   *     </code> if the first result is an update count or there is no result
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or an argument is supplied to this method
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @see Statement#execute
+   * @see Statement#getResultSet
+   * @see Statement#getUpdateCount
+   * @see Statement#getMoreResults
+   */
+  @Override
+  public boolean execute() throws SQLException {
+    executeInternal();
+    handleParameterOutput();
+    if (results.size() > 0) {
+      currResult = results.remove(0);
+      return currResult instanceof Result;
+    }
+    return false;
+  }
+
+  @Override
+  public void setMaxRows(int max) throws SQLException {
+    super.setMaxRows(max);
+    if (canUseServerMaxRows && prepareResult != null) {
+      prepareResult.decrementUse(con.getClient(), this);
+      prepareResult = null;
+    }
+  }
+
+  @Override
+  public void setLargeMaxRows(long max) throws SQLException {
+    super.setLargeMaxRows(max);
+    if (canUseServerMaxRows && prepareResult != null) {
+      prepareResult.decrementUse(con.getClient(), this);
+      prepareResult = null;
+    }
+  }
+
+  @Override
+  public void setQueryTimeout(int seconds) throws SQLException {
+    super.setQueryTimeout(seconds);
+    if (canUseServerTimeout && prepareResult != null) {
+      prepareResult.decrementUse(con.getClient(), this);
+      prepareResult = null;
+    }
+  }
+
+  /**
+   * Executes the SQL query in this <code>PreparedStatement</code> object and returns the <code>
+   * ResultSet</code> object generated by the query.
+   *
+   * @return a <code>ResultSet</code> object that contains the data produced by the query; never
+   *     <code>null</code>
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or the SQL statement does not return a <code>ResultSet
+   *     </code> object
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   */
+  @Override
+  public ResultSet executeQuery() throws SQLException {
+    executeInternal();
+    handleParameterOutput();
+    if (results.size() > 0) {
+      currResult = results.remove(0);
+      if (currResult instanceof Result) return (Result) currResult;
+    }
+    return new CompleteResult(new ColumnDecoder[0], new byte[0][], con.getContext());
+  }
+
+  /**
+   * Executes the SQL statement in this <code>PreparedStatement</code> object, which must be an SQL
+   * Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+   * <code>DELETE</code>; or an SQL statement that returns nothing, such as a DDL statement.
+   *
+   * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0
+   *     for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or the SQL statement returns a <code>ResultSet</code> object
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   */
+  @Override
+  public int executeUpdate() throws SQLException {
+    return (int) executeLargeUpdate();
+  }
+
+  /**
+   * Executes the SQL statement in this <code>PreparedStatement</code> object, which must be an SQL
+   * Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
+   * <code>DELETE</code>; or an SQL statement that returns nothing, such as a DDL statement.
+   *
+   * <p>This method should be used when the returned row count may exceed {@link Integer#MAX_VALUE}.
+   *
+   * <p>The default implementation will throw {@code UnsupportedOperationException}
+   *
+   * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0
+   *     for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs; this method is called on a closed
+   *     <code>PreparedStatement</code> or the SQL statement returns a <code>ResultSet</code> object
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @since 1.8
+   */
+  @Override
+  public long executeLargeUpdate() throws SQLException {
+    executeInternal();
+    handleParameterOutput();
+    currResult = results.remove(0);
+    if (currResult instanceof Result) {
+      throw exceptionFactory()
+          .create("the given SQL statement produces an unexpected ResultSet object", "HY000");
+    }
+    return ((OkPacket) currResult).getAffectedRows();
+  }
+
+  /**
+   * Handle output parameter result-set (only for CallableStatement)
+   *
+   * @throws SQLException if any error occurs
+   */
+  protected void handleParameterOutput() throws SQLException {}
+
+  /**
+   * Adds a set of parameters to this <code>PreparedStatement</code> object's batch of commands.
+   *
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>PreparedStatement</code>
+   * @see Statement#addBatch
+   * @since 1.2
+   */
+  @Override
+  public void addBatch() throws SQLException {
+    validParameters();
+    if (batchParameters == null) batchParameters = new ArrayList<>();
+    batchParameters.add(parameters);
+    parameters = parameters.clone();
+  }
+
+  /**
+   * Validated that all parameters have been set.
+   *
+   * @throws SQLException if number of parameters doesn't correspond to expected number
+   */
+  protected void validParameters() throws SQLException {
+    if (prepareResult != null) {
+      for (int i = 0; i < prepareResult.getParameters().length; i++) {
+        if (!parameters.containsKey(i)) {
+          throw exceptionFactory()
+              .create("Parameter at position " + (i + 1) + " is not set", "07004");
+        }
+      }
+    } else {
+
+      if (batchParameters != null
+          && !batchParameters.isEmpty()
+          && parameters.size() < batchParameters.get(0).size()) {
+        // ensure batch parameters set same number
+        throw exceptionFactory()
+            .create(
+                "batch set of parameters differ from previous set. All parameters must be set",
+                "07004");
+      }
+
+      // ensure all parameters are set
+      for (int i = 0; i < parameters.size(); i++) {
+        if (!parameters.containsKey(i)) {
+          throw exceptionFactory()
+              .create("Parameter at position " + (i + 1) + " is not set", "07004");
+        }
+      }
+    }
+  }
+
+  /**
+   * Retrieves a <code>ResultSetMetaData</code> object that contains information about the columns
+   * of the <code>ResultSet</code> object that will be returned when this <code>PreparedStatement
+   * </code> object is executed.
+   *
+   * <p>Because a <code>PreparedStatement</code> object is precompiled, it is possible to know about
+   * the <code>ResultSet</code> object that it will return without having to execute it.
+   * Consequently, it is possible to invoke the method <code>getMetaData</code> on a <code>
+   * PreparedStatement</code> object rather than waiting to execute it and then invoking the <code>
+   * ResultSet.getMetaData</code> method on the <code>ResultSet</code> object that is returned.
+   *
+   * <p><B>NOTE:</B> Using this method may be expensive for some drivers due to the lack of
+   * underlying DBMS support.
+   *
+   * @return the description of a <code>ResultSet</code> object's columns or <code>null</code> if
+   *     the driver cannot return a <code>ResultSetMetaData</code> object
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>PreparedStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.2
+   */
+  @Override
+  public ResultSetMetaData getMetaData() throws SQLException {
+
+    // send COM_STMT_PREPARE
+    if (prepareResult == null) {
+      con.getClient().execute(new PreparePacket(escapeTimeout(sql)), this, true);
+    }
+
+    return new org.mariadb.jdbc.client.result.ResultSetMetaData(
+        exceptionFactory(), prepareResult.getColumns(), con.getContext().getConf(), false);
+  }
+
+  /**
+   * Retrieves the number, types and properties of this <code>PreparedStatement</code> object's
+   * parameters.
+   *
+   * @return a <code>ParameterMetaData</code> object that contains information about the number,
+   *     types and properties for each parameter marker of this <code>PreparedStatement</code>
+   *     object
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>PreparedStatement</code>
+   * @see ParameterMetaData
+   * @since 1.4
+   */
+  @Override
+  public java.sql.ParameterMetaData getParameterMetaData() throws SQLException {
+    // send COM_STMT_PREPARE
+    if (prepareResult == null) {
+      con.getClient().execute(new PreparePacket(escapeTimeout(sql)), this, true);
+    }
+
+    return new ParameterMetaData(exceptionFactory(), prepareResult.getParameters());
+  }
+
+  @Override
+  public int[] executeBatch() throws SQLException {
+    checkNotClosed();
+    if (batchParameters == null || batchParameters.isEmpty()) return new int[0];
+    lock.lock();
+    try {
+      executeInternalPreparedBatch();
+
+      int[] updates = new int[batchParameters.size()];
+      if (results.size() != updates.length) {
+        for (int i = 0; i < updates.length; i++) {
+          updates[i] = Statement.SUCCESS_NO_INFO;
+        }
+      } else {
+        for (int i = 0; i < updates.length; i++) {
+          if (results.get(i) instanceof OkPacket) {
+            updates[i] = (int) ((OkPacket) results.get(i)).getAffectedRows();
+          } else {
+            updates[i] = org.mariadb.jdbc.Statement.SUCCESS_NO_INFO;
+          }
+        }
+      }
+      currResult = results.remove(0);
+      return updates;
+
+    } finally {
+      localInfileInputStream = null;
+      batchParameters.clear();
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public long[] executeLargeBatch() throws SQLException {
+    checkNotClosed();
+    if (batchParameters == null || batchParameters.isEmpty()) return new long[0];
+    lock.lock();
+    try {
+      executeInternalPreparedBatch();
+
+      long[] updates = new long[batchParameters.size()];
+      if (results.size() != updates.length) {
+        for (int i = 0; i < updates.length; i++) {
+          updates[i] = Statement.SUCCESS_NO_INFO;
+        }
+      } else {
+        for (int i = 0; i < updates.length; i++) {
+          if (results.get(i) instanceof OkPacket) {
+            updates[i] = ((OkPacket) results.get(i)).getAffectedRows();
+          } else {
+            updates[i] = org.mariadb.jdbc.Statement.SUCCESS_NO_INFO;
+          }
+        }
+      }
+
+      currResult = results.remove(0);
+      return updates;
+
+    } finally {
+      batchParameters.clear();
+      lock.unlock();
+    }
+  }
+
+  private ExceptionFactory exceptionFactory() {
+    return con.getExceptionFactory().of(this);
+  }
+
+  @Override
+  public void close() throws SQLException {
+    if (prepareResult != null) {
+      prepareResult.decrementUse(con.getClient(), this);
+      prepareResult = null;
+    }
+    con.fireStatementClosed(this);
+    super.close();
+  }
+
+  /**
+   * reset prepare statement in case of a failover. (Command need then to be re-prepared on server)
+   */
+  public void reset() {
+    lock.lock();
+    try {
+      prepareResult = null;
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  @Override
+  public String toString() {
+    return "ServerPreparedStatement{" + super.toString() + '}';
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/SimpleParameterMetaData.java b/src/main/java/org/mariadb/jdbc/SimpleParameterMetaData.java
new file mode 100644
index 0000000..96b63fc
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/SimpleParameterMetaData.java
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.SQLException;
+import org.mariadb.jdbc.export.ExceptionFactory;
+
+/** Simple parameter metadata, when the only reliable think is the number of parameter */
+public class SimpleParameterMetaData implements java.sql.ParameterMetaData {
+
+  private final int paramCount;
+  private final ExceptionFactory exceptionFactory;
+
+  /**
+   * Constructor
+   *
+   * @param exceptionFactory connection exception factory
+   * @param paramCount parameter count
+   */
+  protected SimpleParameterMetaData(ExceptionFactory exceptionFactory, int paramCount) {
+    this.exceptionFactory = exceptionFactory;
+    this.paramCount = paramCount;
+  }
+
+  /**
+   * Retrieves the number of parameters in the <code>PreparedStatement</code> object for which this
+   * <code>ParameterMetaData</code> object contains information.
+   *
+   * @return the number of parameters
+   */
+  @Override
+  public int getParameterCount() {
+    return paramCount;
+  }
+
+  private void checkIndex(int index) throws SQLException {
+    if (index < 1 || index > paramCount) {
+      throw exceptionFactory.create(
+          String.format(
+              "Wrong index position. Is %s but must be in 1-%s range", index, paramCount));
+    }
+  }
+
+  /**
+   * Retrieves whether null values are allowed in the designated parameter.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return the nullability status of the given parameter; one of <code>
+   *     ParameterMetaData.parameterNoNulls</code>, <code>ParameterMetaData.parameterNullable</code>
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public int isNullable(int idx) throws SQLException {
+    checkIndex(idx);
+    return java.sql.ParameterMetaData.parameterNullable;
+  }
+
+  /**
+   * Retrieves whether values for the designated parameter can be signed numbers.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public boolean isSigned(int idx) throws SQLException {
+    checkIndex(idx);
+    return true;
+  }
+
+  /**
+   * Retrieves the designated parameter's specified column size.
+   *
+   * <p>The returned value represents the maximum column size for the given parameter. For numeric
+   * data, this is the maximum precision. For character data, this is the length in characters. For
+   * datetime datatypes, this is the length in characters of the String representation (assuming the
+   * maximum allowed precision of the fractional seconds component). For binary data, this is the
+   * length in bytes. For the ROWID datatype, this is the length in bytes. 0 is returned for data
+   * types where the column size is not applicable.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return precision
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public int getPrecision(int idx) throws SQLException {
+    checkIndex(idx);
+    throw exceptionFactory.create("Unknown parameter metadata precision");
+  }
+
+  /**
+   * Retrieves the designated parameter's number of digits to right of the decimal point. 0 is
+   * returned for data types where the scale is not applicable. Parameter type are not sent by
+   * server. See * https://jira.mariadb.org/browse/CONJ-568 and
+   * https://jira.mariadb.org/browse/MDEV-15031
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return scale
+   * @throws SQLException if a database access error occurs
+   */
+  @Override
+  public int getScale(int idx) throws SQLException {
+    checkIndex(idx);
+    throw exceptionFactory.create("Unknown parameter metadata scale");
+  }
+
+  /**
+   * Retrieves the designated parameter's SQL type. Parameter type are not sent by server. See
+   * https://jira.mariadb.org/browse/CONJ-568 and https://jira.mariadb.org/browse/MDEV-15031
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return SQL types from <code>java.sql.Types</code>
+   * @throws SQLException because not supported
+   */
+  @Override
+  public int getParameterType(int idx) throws SQLException {
+    checkIndex(idx);
+    throw exceptionFactory.create("Getting parameter type metadata is not supported", "0A000", -1);
+  }
+
+  /**
+   * Retrieves the designated parameter's database-specific type name.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return type the name used by the database. If the parameter type is a user-defined type, then
+   *     a fully-qualified type name is returned.
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public String getParameterTypeName(int idx) throws SQLException {
+    checkIndex(idx);
+    throw exceptionFactory.create("Unknown parameter metadata type name");
+  }
+
+  /**
+   * Retrieves the fully-qualified name of the Java class whose instances should be passed to the
+   * method <code>PreparedStatement.setObject</code>.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return the fully-qualified name of the class in the Java programming language that would be
+   *     used by the method <code>PreparedStatement.setObject</code> to set the value in the
+   *     specified parameter. This is the class name used for custom mapping.
+   * @throws SQLException if wrong index
+   */
+  @Override
+  public String getParameterClassName(int idx) throws SQLException {
+    checkIndex(idx);
+    throw exceptionFactory.create("Unknown parameter metadata class name", "0A000");
+  }
+
+  /**
+   * Retrieves the designated parameter's mode.
+   *
+   * @param idx the first parameter is 1, the second is 2, ...
+   * @return mode of the parameter; one of <code>ParameterMetaData.parameterModeIn</code>, <code>
+   *     ParameterMetaData.parameterModeOut</code>, or <code>ParameterMetaData.parameterModeInOut
+   *     </code> <code>ParameterMetaData.parameterModeUnknown</code>.
+   */
+  @Override
+  public int getParameterMode(int idx) throws SQLException {
+    checkIndex(idx);
+    return java.sql.ParameterMetaData.parameterModeIn;
+  }
+
+  /**
+   * Returns an object that implements the given interface to allow access to non-standard methods,
+   * or standard methods not exposed by the proxy.
+   *
+   * <p>If the receiver implements the interface then the result is the receiver or a proxy for the
+   * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the
+   * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of
+   * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If
+   * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException
+   * </code> is thrown.
+   *
+   * @param iface A Class defining an interface that the result must implement.
+   * @return an object that implements the interface. Maybe a proxy for the actual implementing
+   *     object.
+   * @throws SQLException If no object found that implements the interface
+   */
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
+  }
+
+  /**
+   * Returns true if this either implements the interface argument or is directly or indirectly a
+   * wrapper for an object that does. Returns false otherwise. If this implements the interface then
+   * return true, else if this is a wrapper then return the result of recursively calling <code>
+   * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not
+   * a wrapper, return false. This method should be implemented as a low-cost operation compared to
+   * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>
+   * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same
+   * argument should succeed.
+   *
+   * @param iface a Class defining an interface.
+   * @return true if this implements the interface or directly or indirectly wraps an object that
+   *     does.
+   */
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/Statement.java b/src/main/java/org/mariadb/jdbc/Statement.java
new file mode 100644
index 0000000..aaf720b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/Statement.java
@@ -0,0 +1,1560 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import static org.mariadb.jdbc.util.constants.Capabilities.LOCAL_FILES;
+
+import java.io.InputStream;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.client.result.Result;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.client.QueryPacket;
+import org.mariadb.jdbc.message.server.OkPacket;
+import org.mariadb.jdbc.util.NativeSql;
+import org.mariadb.jdbc.util.constants.ColumnFlags;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Statement implementation */
+public class Statement implements java.sql.Statement {
+
+  private List<String> batchQueries;
+
+  /** result-set type */
+  protected final int resultSetType;
+  /** concurrency */
+  protected final int resultSetConcurrency;
+  /** thread safe locker */
+  protected final ReentrantLock lock;
+  /** can use server query timeout */
+  protected final boolean canUseServerTimeout;
+  /** can use server row limitation */
+  protected final boolean canUseServerMaxRows;
+  /** connection */
+  protected final Connection con;
+  /** required query timeout */
+  protected int queryTimeout;
+  /** maximum row number */
+  protected long maxRows;
+  /** fetch size */
+  protected int fetchSize;
+  /** automatic generated keys result required */
+  protected int autoGeneratedKeys;
+  /** close statement on resultset completion */
+  protected boolean closeOnCompletion;
+  /** closed flag */
+  protected boolean closed;
+  /** escape processing */
+  protected boolean escape;
+  /** last execution results */
+  protected List<Completion> results;
+  /** current results */
+  protected Completion currResult;
+  /** streaming load data infile data */
+  protected InputStream localInfileInputStream;
+
+  /**
+   * Constructor
+   *
+   * @param con connection
+   * @param lock thread safe locker
+   * @param canUseServerTimeout can use server timeout
+   * @param canUseServerMaxRows can use server row number limitation
+   * @param autoGeneratedKeys automatic generated keys result required
+   * @param resultSetType result-set type
+   * @param resultSetConcurrency concurrency
+   * @param defaultFetchSize fetch size
+   */
+  public Statement(
+      Connection con,
+      ReentrantLock lock,
+      boolean canUseServerTimeout,
+      boolean canUseServerMaxRows,
+      int autoGeneratedKeys,
+      int resultSetType,
+      int resultSetConcurrency,
+      int defaultFetchSize) {
+    this.con = con;
+    this.lock = lock;
+    this.resultSetConcurrency = resultSetConcurrency;
+    this.resultSetType = resultSetType;
+    this.autoGeneratedKeys = autoGeneratedKeys;
+    this.canUseServerTimeout = canUseServerTimeout;
+    this.canUseServerMaxRows = canUseServerMaxRows;
+    this.fetchSize = defaultFetchSize;
+  }
+
+  private ExceptionFactory exceptionFactory() {
+    return con.getExceptionFactory().of(this);
+  }
+
+  /**
+   * Set current local infile stream
+   *
+   * @param inputStream stream
+   * @throws SQLException if statement is already closed
+   */
+  public void setLocalInfileInputStream(InputStream inputStream) throws SQLException {
+    checkNotClosed();
+    localInfileInputStream = inputStream;
+  }
+
+  /**
+   * Executes the given SQL statement, which returns a single <code>ResultSet</code> object.
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql an SQL statement to be sent to the database, typically a static SQL <code>SELECT
+   *     </code> statement
+   * @return a <code>ResultSet</code> object that contains the data produced by the given query;
+   *     never <code>null</code>
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the given SQL statement produces anything other than a single
+   *     <code>ResultSet</code> object, the method is called on a <code>PreparedStatement</code> or
+   *     <code>CallableStatement</code>
+   * @throws java.sql.SQLTimeoutException when the driver has determined that the timeout value that
+   *     was specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   */
+  @Override
+  public ResultSet executeQuery(String sql) throws SQLException {
+    executeInternal(sql, Statement.NO_GENERATED_KEYS);
+    currResult = results.remove(0);
+    if (currResult instanceof Result) return (Result) currResult;
+    return new CompleteResult(new ColumnDecoder[0], new byte[0][], con.getContext());
+  }
+
+  /**
+   * Executes the given SQL statement, which may be an <code>INSERT</code>, <code>UPDATE</code>, or
+   * <code>DELETE</code> statement or an SQL statement that returns nothing, such as an SQL DDL
+   * statement.
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>,
+   *     <code>UPDATE</code> or <code>DELETE</code>; or an SQL statement that returns nothing, such
+   *     as a DDL statement.
+   * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0
+   *     for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the given SQL statement produces a <code>ResultSet</code> object,
+   *     the method is called on a <code>PreparedStatement</code> or <code>CallableStatement</code>
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   */
+  @Override
+  public int executeUpdate(String sql) throws SQLException {
+    return executeUpdate(sql, Statement.NO_GENERATED_KEYS);
+  }
+
+  /**
+   * Releases this <code>Statement</code> object's database and JDBC resources immediately instead
+   * of waiting for this to happen when it is automatically closed. It is generally good practice to
+   * release resources as soon as you are finished with them to avoid tying up database resources.
+   *
+   * <p>Calling the method <code>close</code> on a <code>Statement</code> object that is already
+   * closed has no effect.
+   *
+   * <p><B>Note:</B>When a <code>Statement</code> object is closed, its current <code>ResultSet
+   * </code> object, if one exists, is also closed.
+   *
+   * @throws SQLException if a database access error occurs
+   */
+  @Override
+  public void close() throws SQLException {
+    if (!closed) {
+      closed = true;
+
+      if (currResult != null && currResult instanceof Result) {
+        ((Result) currResult).closeFromStmtClose(lock);
+      }
+
+      // close result-set
+      if (results != null && !results.isEmpty()) {
+        for (Completion completion : results) {
+          if (completion instanceof Result) {
+            ((Result) completion).closeFromStmtClose(lock);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Abort current command result if streaming. result-set will be incomplete and closed, but ensure
+   * connection state
+   */
+  public void abort() {
+    lock.lock();
+    try {
+      if (!closed) {
+        closed = true;
+
+        if (currResult != null && currResult instanceof Result) {
+          ((Result) currResult).abort();
+        }
+
+        // close result-set
+        if (results != null) {
+          for (Completion completion : results) {
+            if (completion instanceof Result) {
+              ((Result) completion).abort();
+            }
+          }
+        }
+      }
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  /**
+   * Retrieves the maximum number of bytes that can be returned for character and binary column
+   * values in a <code>ResultSet</code> object produced by this <code>Statement</code> object. This
+   * limit applies only to <code>BINARY</code>, <code>VARBINARY</code>, <code>LONGVARBINARY</code>,
+   * <code>CHAR</code>, <code>VARCHAR</code>, <code>NCHAR</code>, <code>NVARCHAR</code>, <code>
+   * LONGNVARCHAR</code> and <code>LONGVARCHAR</code> columns. If the limit is exceeded, the excess
+   * data is silently discarded.
+   *
+   * @return the current column size limit for columns storing character and binary values; zero
+   *     means there is no limit
+   * @see #setMaxFieldSize
+   */
+  @Override
+  public int getMaxFieldSize() {
+    return 0;
+  }
+
+  /**
+   * NOT SUPPORTED.
+   *
+   * @see #getMaxFieldSize
+   */
+  @Override
+  public void setMaxFieldSize(int max) {}
+
+  /**
+   * Retrieves the maximum number of rows that a <code>ResultSet</code> object produced by this
+   * <code>Statement</code> object can contain. If this limit is exceeded, the excess rows are
+   * silently dropped.
+   *
+   * @return the current maximum number of rows for a <code>ResultSet</code> object produced by this
+   *     <code>Statement</code> object; zero means there is no limit
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @see #setMaxRows
+   */
+  @Override
+  public int getMaxRows() throws SQLException {
+    checkNotClosed();
+    return (int) maxRows;
+  }
+
+  /**
+   * Sets the limit for the maximum number of rows that any <code>ResultSet</code> object generated
+   * by this <code>Statement</code> object can contain to the given number. If the limit is
+   * exceeded, the excess rows are silently dropped.
+   *
+   * @param max the new max rows limit; zero means there is no limit
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code> or the condition {@code max >= 0} is not satisfied
+   * @see #getMaxRows
+   */
+  @Override
+  public void setMaxRows(int max) throws SQLException {
+    checkNotClosed();
+    if (max < 0) {
+      throw exceptionFactory().create("max rows cannot be negative : asked for " + max, "42000");
+    }
+    maxRows = max;
+  }
+
+  /**
+   * Sets escape processing on or off. If escape scanning is on (the default), the driver will do
+   * escape substitution before sending the SQL statement to the database.
+   *
+   * <p>The {@code Connection} and {@code DataSource} property {@code escapeProcessing} may be used
+   * to change the default escape processing behavior. A value of true (the default) enables escape
+   * Processing for all {@code Statement} objects. A value of false disables escape processing for
+   * all {@code Statement} objects. The {@code setEscapeProcessing} method may be used to specify
+   * the escape processing behavior for an individual {@code Statement} object.
+   *
+   * <p>Note: Since prepared statements have usually been parsed prior to making this call,
+   * disabling escape processing for <code>PreparedStatements</code> objects will have no effect.
+   *
+   * @param enable <code>true</code> to enable escape processing; <code>false</code> to disable it
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   */
+  @Override
+  public void setEscapeProcessing(boolean enable) throws SQLException {
+    checkNotClosed();
+    this.escape = enable;
+  }
+
+  /**
+   * Retrieves the number of seconds the driver will wait for a <code>Statement</code> object to
+   * execute. If the limit is exceeded, a <code>SQLException</code> is thrown.
+   *
+   * @return the current query timeout limit in seconds; zero means there is no limit
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @see #setQueryTimeout
+   */
+  @Override
+  public int getQueryTimeout() throws SQLException {
+    checkNotClosed();
+    return queryTimeout;
+  }
+
+  /**
+   * Sets the number of seconds the driver will wait for a <code>Statement</code> object to execute
+   * to the given number of seconds. By default, there is no limit on the amount of time allowed for
+   * a running statement to complete. If the limit is exceeded, an <code>SQLTimeoutException</code>
+   * is thrown. A JDBC driver must apply this limit to the <code>execute</code>, <code>executeQuery
+   * </code> and <code>executeUpdate</code> methods.
+   *
+   * <p><strong>Note:</strong> JDBC driver implementations may also apply this limit to {@code
+   * ResultSet} methods (consult your driver vendor documentation for details).
+   *
+   * <p><strong>Note:</strong> In the case of {@code Statement} batching, it is implementation
+   * defined whether the time-out is applied to individual SQL commands added via the {@code
+   * addBatch} method or to the entire batch of SQL commands invoked by the {@code executeBatch}
+   * method (consult your driver vendor documentation for details).
+   *
+   * @param seconds the new query timeout limit in seconds; zero means there is no limit
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code> or the condition {@code seconds >= 0} is not satisfied
+   * @see #getQueryTimeout
+   */
+  @Override
+  public void setQueryTimeout(int seconds) throws SQLException {
+    if (seconds < 0) {
+      throw exceptionFactory()
+          .create("Query timeout cannot be negative : asked for " + seconds, "42000");
+    }
+    this.queryTimeout = seconds;
+  }
+
+  /**
+   * Cancels this <code>Statement</code> object if both the DBMS and driver support aborting an SQL
+   * statement. This method can be used by one thread to cancel a statement that is being executed
+   * by another thread.
+   *
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   */
+  @Override
+  public void cancel() throws SQLException {
+    checkNotClosed();
+    boolean locked = lock.tryLock();
+    // if any query is active, lock is set.
+    // this avoids trying to execute a KILL QUERY if no query is running.
+    if (!locked) {
+      con.cancelCurrentQuery();
+    } else {
+      lock.unlock();
+    }
+  }
+
+  /**
+   * Retrieves the first warning reported by calls on this <code>Statement</code> object. Subsequent
+   * <code>Statement</code> object warnings will be chained to this <code>SQLWarning</code> object.
+   *
+   * <p>The warning chain is automatically cleared each time a statement is (re)executed. This
+   * method may not be called on a closed <code>Statement</code> object; doing so will cause an
+   * <code>SQLException</code> to be thrown.
+   *
+   * <p><B>Note:</B> If you are processing a <code>ResultSet</code> object, any warnings associated
+   * with reads on that <code>ResultSet</code> object will be chained on it rather than on the
+   * <code>Statement</code> object that produced it.
+   *
+   * @return the first <code>SQLWarning</code> object or <code>null</code> if there are no warnings
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   */
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    return con.getWarnings();
+  }
+
+  /**
+   * Clears all the warnings reported on this <code>Statement</code> object. After a call to this
+   * method, the method <code>getWarnings</code> will return <code>null</code> until a new warning
+   * is reported for this <code>Statement</code> object.
+   */
+  @Override
+  public void clearWarnings() {
+    con.getContext().setWarning(0);
+  }
+
+  /**
+   * Sets the SQL cursor name to the given <code>String</code>, which will be used by subsequent
+   * <code>Statement</code> object <code>execute</code> methods. This name can then be used in SQL
+   * positioned update or delete statements to identify the current row in the <code>ResultSet
+   * </code> object generated by this statement. If the database does not support positioned
+   * update/delete, this method is a noop. To ensure that a cursor has the proper isolation level to
+   * support updates, the cursor's <code>SELECT</code> statement should have the form <code>
+   * SELECT FOR UPDATE</code>. If <code>FOR UPDATE</code> is not present, positioned updates may
+   * fail.
+   *
+   * <p><B>Note:</B> By definition, the execution of positioned updates and deletes must be done by
+   * a different <code>Statement</code> object than the one that generated the <code>ResultSet
+   * </code> object being used for positioning. Also, cursor names must be unique within a
+   * connection.
+   *
+   * @param name the new cursor name, which must be unique within a connection
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   */
+  @Override
+  public void setCursorName(String name) throws SQLException {
+    throw exceptionFactory().notSupported("Cursors are not supported");
+  }
+
+  /**
+   * Executes the given SQL statement, which may return multiple results. In some (uncommon)
+   * situations, a single SQL statement may return multiple result sets and/or update counts.
+   * Normally you can ignore this unless you are (1) executing a stored procedure that you know may
+   * return multiple results or (2) you are dynamically executing an unknown SQL string.
+   *
+   * <p>The <code>execute</code> method executes an SQL statement and indicates the form of the
+   * first result. You must then use the methods <code>getResultSet</code> or <code>getUpdateCount
+   * </code> to retrieve the result, and <code>getMoreResults</code> to move to any subsequent
+   * result(s).
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql any SQL statement
+   * @return <code>true</code> if the first result is a <code>ResultSet</code> object; <code>false
+   *     </code> if it is an update count or there are no results
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the method is called on a <code>PreparedStatement</code> or <code>
+   *     CallableStatement</code>
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @see #getResultSet
+   * @see #getUpdateCount
+   * @see #getMoreResults
+   */
+  @Override
+  public boolean execute(String sql) throws SQLException {
+    return execute(sql, Statement.NO_GENERATED_KEYS);
+  }
+
+  /**
+   * Retrieves the current result as a <code>ResultSet</code> object. This method should be called
+   * only once per result.
+   *
+   * @return the current result as a <code>ResultSet</code> object or <code>null</code> if the
+   *     result is an update count or there are no more results
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @see #execute
+   */
+  @Override
+  public ResultSet getResultSet() throws SQLException {
+    checkNotClosed();
+    if (currResult instanceof Result) {
+      return (Result) currResult;
+    }
+    return null;
+  }
+
+  /**
+   * Retrieves the current result as an update count; if the result is a <code>ResultSet</code>
+   * object or there are no more results, -1 is returned. This method should be called only once per
+   * result.
+   *
+   * @return the current result as an update count; -1 if the current result is a <code>ResultSet
+   *     </code> object or there are no more results
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @see #execute
+   */
+  @Override
+  public int getUpdateCount() throws SQLException {
+    checkNotClosed();
+    if (currResult instanceof OkPacket) {
+      return (int) ((OkPacket) currResult).getAffectedRows();
+    }
+    return -1;
+  }
+
+  /**
+   * Moves to this <code>Statement</code> object's next result, returns <code>true</code> if it is a
+   * <code>ResultSet</code> object, and implicitly closes any current <code>ResultSet</code>
+   * object(s) obtained with the method <code>getResultSet</code>.
+   *
+   * <p>There are no more results when the following is true:
+   *
+   * <PRE>{@code
+   * // stmt is a Statement object
+   * ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))
+   * }</PRE>
+   *
+   * @return <code>true</code> if the next result is a <code>ResultSet</code> object; <code>false
+   *     </code> if it is an update count or there are no more results
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @see #execute
+   */
+  @Override
+  public boolean getMoreResults() throws SQLException {
+    return getMoreResults(Statement.CLOSE_CURRENT_RESULT);
+  }
+
+  /**
+   * Retrieves the direction for fetching rows from database tables that is the default for result
+   * sets generated from this <code>Statement</code> object. If this <code>Statement</code> object
+   * has not set a fetch direction by calling the method <code>setFetchDirection</code>, the return
+   * value is implementation-specific.
+   *
+   * @return the default fetch direction for result sets generated from this <code>Statement</code>
+   *     object
+   * @see #setFetchDirection
+   * @since 1.2
+   */
+  @Override
+  public int getFetchDirection() {
+    return ResultSet.FETCH_FORWARD;
+  }
+
+  /**
+   * Gives the driver a hint as to the direction in which rows will be processed in <code>ResultSet
+   * </code> objects created using this <code>Statement</code> object. The default value is <code>
+   * ResultSet.FETCH_FORWARD</code>.
+   *
+   * <p>Note that this method sets the default fetch direction for result sets generated by this
+   * <code>Statement</code> object. Each result set has its own methods for getting and setting its
+   * own fetch direction.
+   *
+   * @param direction the initial direction for processing rows
+   */
+  @Override
+  public void setFetchDirection(int direction) {
+    // not supported
+  }
+
+  /**
+   * Retrieves the number of result set rows that is the default fetch size for <code>ResultSet
+   * </code> objects generated from this <code>Statement</code> object. If this <code>Statement
+   * </code> object has not set a fetch size by calling the method <code>setFetchSize</code>, the
+   * return value is implementation-specific.
+   *
+   * @return the default fetch size for result sets generated from this <code>Statement</code>
+   *     object
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @see #setFetchSize
+   */
+  @Override
+  public int getFetchSize() throws SQLException {
+    checkNotClosed();
+    return this.fetchSize;
+  }
+
+  /**
+   * Gives the JDBC driver a hint as to the number of rows that should be fetched from the database
+   * when more rows are needed for <code>ResultSet</code> objects generated by this <code>Statement
+   * </code>. If the value specified is zero, then the hint is ignored. The default value is zero.
+   *
+   * @param rows the number of rows to fetch
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code> or the condition {@code rows >= 0} is not satisfied.
+   * @see #getFetchSize
+   * @since 1.2
+   */
+  @Override
+  public void setFetchSize(int rows) throws SQLException {
+    if (rows < 0) {
+      throw exceptionFactory().create("invalid fetch size");
+    }
+    this.fetchSize = rows;
+  }
+
+  /**
+   * Retrieves the result set concurrency for <code>ResultSet</code> objects generated by this
+   * <code>Statement</code> object.
+   *
+   * @return either <code>ResultSet.CONCUR_READ_ONLY</code> or <code>ResultSet.CONCUR_UPDATABLE
+   *     </code>
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   */
+  @Override
+  public int getResultSetConcurrency() throws SQLException {
+    checkNotClosed();
+    return this.resultSetConcurrency;
+  }
+
+  /**
+   * Retrieves the result set type for <code>ResultSet</code> objects generated by this <code>
+   * Statement</code> object.
+   *
+   * @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, <code>
+   *     ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+   * @since 1.2
+   */
+  @Override
+  public int getResultSetType() {
+    return this.resultSetType;
+  }
+
+  /**
+   * Adds the given SQL command to the current list of commands for this <code>Statement</code>
+   * object. The commands in this list can be executed as a batch by calling the method <code>
+   * executeBatch</code>.
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql typically this is an SQL <code>INSERT</code> or <code>UPDATE</code> statement
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the driver does not support batch updates, the method is called on
+   *     a <code>PreparedStatement</code> or <code>CallableStatement</code>
+   * @see #executeBatch
+   * @see DatabaseMetaData#supportsBatchUpdates
+   */
+  @Override
+  public void addBatch(String sql) throws SQLException {
+    if (sql == null) {
+      throw exceptionFactory().create("null cannot be set to addBatch(String sql)");
+    }
+    if (batchQueries == null) batchQueries = new ArrayList<>();
+    batchQueries.add(escape ? NativeSql.parse(sql, con.getContext()) : sql);
+  }
+
+  /**
+   * Empties this <code>Statement</code> object's current list of SQL commands.
+   *
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code> or the driver does not support batch updates
+   * @see #addBatch
+   * @see DatabaseMetaData#supportsBatchUpdates
+   * @since 1.2
+   */
+  @Override
+  public void clearBatch() throws SQLException {
+    checkNotClosed();
+    if (batchQueries == null) {
+      batchQueries = new ArrayList<>();
+    } else {
+      batchQueries.clear();
+    }
+  }
+
+  /**
+   * Submits a batch of commands to the database for execution and if all commands execute
+   * successfully, returns an array of update counts. The <code>int</code> elements of the array
+   * that is returned are ordered to correspond to the commands in the batch, which are ordered
+   * according to the order in which they were added to the batch. The elements in the array
+   * returned by the method <code>executeBatch</code> may be one of the following:
+   *
+   * <OL>
+   *   <LI>A number greater than or equal to zero -- indicates that the command was processed
+   *       successfully and is an update count giving the number of rows in the database that were
+   *       affected by the command's execution
+   *   <LI>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the command was processed
+   *       successfully but that the number of rows affected is unknown
+   *       <p>If one of the commands in a batch update fails to execute properly, this method throws
+   *       a <code>BatchUpdateException</code>, and a JDBC driver may or may not continue to process
+   *       the remaining commands in the batch. However, the driver's behavior must be consistent
+   *       with a particular DBMS, either always continuing to process commands or never continuing
+   *       to process commands. If the driver continues processing after a failure, the array
+   *       returned by the method <code>BatchUpdateException.getUpdateCounts</code> will contain as
+   *       many elements as there are commands in the batch, and at least one of the elements will
+   *       be the following:
+   *   <LI>A value of <code>EXECUTE_FAILED</code> -- indicates that the command failed to execute
+   *       successfully and occurs only if a driver continues to process commands after a command
+   *       fails
+   * </OL>
+   *
+   * <p>The possible implementations and return values have been modified in the Java 2 SDK,
+   * Standard Edition, version 1.3 to accommodate the option of continuing to process commands in a
+   * batch update after a <code>BatchUpdateException</code> object has been thrown.
+   *
+   * @return an array of update counts containing one element for each command in the batch. The
+   *     elements of the array are ordered according to the order in which commands were added to
+   *     the batch.
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code> or the driver does not support batch statements. Throws {@link
+   *     BatchUpdateException} (a subclass of <code>SQLException</code>) if one of the commands sent
+   *     to the database fails to execute properly or attempts to return a result set.
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @see #addBatch
+   * @see DatabaseMetaData#supportsBatchUpdates
+   * @since 1.2
+   */
+  @Override
+  public int[] executeBatch() throws SQLException {
+    checkNotClosed();
+    if (batchQueries == null || batchQueries.isEmpty()) return new int[0];
+    lock.lock();
+    try {
+      // ensure pipelining is possible (no LOAD DATA/XML INFILE commands)
+      boolean possibleLoadLocal = con.getContext().hasClientCapability(LOCAL_FILES);
+      if (possibleLoadLocal) {
+        possibleLoadLocal = false;
+        for (int i = 0; i < batchQueries.size(); i++) {
+          String sql = batchQueries.get(i).toUpperCase(Locale.ROOT);
+          if (sql.contains(" LOCAL ") && sql.contains("LOAD") && sql.contains(" INFILE")) {
+            possibleLoadLocal = true;
+            break;
+          }
+        }
+      }
+
+      List<Completion> res =
+          possibleLoadLocal ? executeInternalBatchStandard() : executeInternalBatchPipeline();
+
+      results = res;
+
+      int[] updates = new int[res.size()];
+      for (int i = 0; i < res.size(); i++) {
+        if (res.get(i) instanceof OkPacket) {
+          updates[i] = (int) ((OkPacket) res.get(i)).getAffectedRows();
+        } else {
+          updates[i] = org.mariadb.jdbc.Statement.SUCCESS_NO_INFO;
+        }
+      }
+      currResult = results.remove(0);
+      batchQueries.clear();
+      return updates;
+
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  /**
+   * Retrieves the <code>Connection</code> object that produced this <code>Statement</code> object.
+   *
+   * @return the connection that produced this statement
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @since 1.2
+   */
+  @Override
+  public Connection getConnection() throws SQLException {
+    checkNotClosed();
+    return con;
+  }
+
+  /**
+   * Moves to this <code>Statement</code> object's next result, deals with any current <code>
+   * ResultSet</code> object(s) according to the instructions specified by the given flag, and
+   * returns <code>true</code> if the next result is a <code>ResultSet</code> object.
+   *
+   * <p>There are no more results when the following is true:
+   *
+   * <PRE>{@code
+   * // stmt is a Statement object
+   * ((stmt.getMoreResults(current) == false) && (stmt.getUpdateCount() == -1))
+   * }</PRE>
+   *
+   * @param current one of the following <code>Statement</code> constants indicating what should
+   *     happen to current <code>ResultSet</code> objects obtained using the method <code>
+   *     getResultSet</code>: <code>Statement.CLOSE_CURRENT_RESULT</code>, <code>
+   *     Statement.KEEP_CURRENT_RESULT</code>, or <code>Statement.CLOSE_ALL_RESULTS</code>
+   * @return <code>true</code> if the next result is a <code>ResultSet</code> object; <code>false
+   *     </code> if it is an update count or there are no more results
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code> or the argument supplied is not one of the following: <code>
+   *     Statement.CLOSE_CURRENT_RESULT</code>, <code>Statement.KEEP_CURRENT_RESULT</code> or <code>
+   *     Statement.CLOSE_ALL_RESULTS</code>
+   * @throws SQLFeatureNotSupportedException if <code>DatabaseMetaData.supportsMultipleOpenResults
+   *     </code> returns <code>false</code> and either <code>Statement.KEEP_CURRENT_RESULT</code> or
+   *     <code>Statement.CLOSE_ALL_RESULTS</code> are supplied as the argument.
+   * @see #execute
+   * @since 1.4
+   */
+  @Override
+  public boolean getMoreResults(int current) throws SQLException {
+    checkNotClosed();
+    if (currResult instanceof ResultSet) {
+      lock.lock();
+      try {
+        Result result = (Result) currResult;
+        if (current == java.sql.Statement.CLOSE_CURRENT_RESULT) {
+          result.close();
+        } else {
+          result.fetchRemaining();
+        }
+        if (result.streaming()
+            && (con.getContext().getServerStatus() & ServerStatus.MORE_RESULTS_EXISTS) > 0) {
+          con.getClient()
+              .readStreamingResults(
+                  results,
+                  fetchSize,
+                  maxRows,
+                  resultSetConcurrency,
+                  resultSetType,
+                  closeOnCompletion);
+        }
+      } finally {
+        lock.unlock();
+      }
+    }
+
+    if (results.size() > 0) {
+      currResult = results.remove(0);
+      return (currResult instanceof Result);
+    }
+    currResult = null;
+    return false;
+  }
+
+  /**
+   * Permit to streaming result to fetch remaining results.
+   *
+   * @throws SQLException if socket error occurs.
+   */
+  public void fetchRemaining() throws SQLException {
+    if (currResult != null && currResult instanceof ResultSet) {
+      Result result = (Result) currResult;
+      result.fetchRemaining();
+      if (result.streaming()
+          && (con.getContext().getServerStatus() & ServerStatus.MORE_RESULTS_EXISTS) > 0) {
+        con.getClient()
+            .readStreamingResults(
+                results, 0, 0L, resultSetConcurrency, resultSetType, closeOnCompletion);
+      }
+    }
+  }
+
+  /**
+   * Retrieves any auto-generated keys created as a result of executing this <code>Statement</code>
+   * object. If this <code>Statement</code> object did not generate any keys, an empty <code>
+   * ResultSet</code> object is returned.
+   *
+   * <p><B>Note:</B>If the columns which represent the auto-generated keys were not specified, the
+   * JDBC driver implementation will determine the columns which best represent the auto-generated
+   * keys.
+   *
+   * @return a <code>ResultSet</code> object containing the auto-generated key(s) generated by the
+   *     execution of this <code>Statement</code> object
+   * @throws SQLException if a database access error occurs or this method is called on a closed
+   *     <code>Statement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @since 1.4
+   */
+  @Override
+  public ResultSet getGeneratedKeys() throws SQLException {
+    checkNotClosed();
+    if (autoGeneratedKeys != java.sql.Statement.RETURN_GENERATED_KEYS) {
+      throw new SQLException(
+          "Cannot return generated keys: query was not set with Statement.RETURN_GENERATED_KEYS");
+    }
+
+    if (currResult instanceof OkPacket) {
+
+      OkPacket ok = ((OkPacket) currResult);
+      if (ok.getLastInsertId() != 0) {
+        List<String[]> insertIds = new ArrayList<>();
+        insertIds.add(new String[] {String.valueOf(ok.getLastInsertId())});
+        for (Completion result : results) {
+          if (result instanceof OkPacket) {
+            insertIds.add(new String[] {String.valueOf(((OkPacket) result).getLastInsertId())});
+          }
+        }
+        String[][] ids = insertIds.toArray(new String[0][]);
+        return CompleteResult.createResultSet(
+            "insert_id",
+            DataType.BIGINT,
+            ids,
+            con.getContext(),
+            ColumnFlags.AUTO_INCREMENT | ColumnFlags.UNSIGNED);
+      }
+    }
+
+    return new CompleteResult(new ColumnDecoder[0], new byte[0][], con.getContext());
+  }
+
+  /**
+   * Executes the given SQL statement and signals the driver with the given flag about whether the
+   * auto-generated keys produced by this <code>Statement</code> object should be made available for
+   * retrieval. The driver will ignore the flag if the SQL statement is not an <code>INSERT</code>
+   * statement, or an SQL statement able to return auto-generated keys (the list of such statements
+   * is vendor-specific).
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>,
+   *     <code>UPDATE</code> or <code>DELETE</code>; or an SQL statement that returns nothing, such
+   *     as a DDL statement.
+   * @param autoGeneratedKeys a flag indicating whether auto-generated keys should be made available
+   *     for retrieval; one of the following constants: <code>Statement.RETURN_GENERATED_KEYS</code>
+   *     <code>Statement.NO_GENERATED_KEYS</code>
+   * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0
+   *     for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the given SQL statement returns a <code>ResultSet</code> object,
+   *     the given constant is not one of those allowed, the method is called on a <code>
+   *     PreparedStatement</code> or <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method with a
+   *     constant of Statement.RETURN_GENERATED_KEYS
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @since 1.4
+   */
+  @Override
+  public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+    executeInternal(sql, autoGeneratedKeys);
+
+    currResult = results.remove(0);
+    if (currResult instanceof Result) {
+      throw exceptionFactory()
+          .create("the given SQL statement produces an unexpected ResultSet object", "HY000");
+    }
+    return (int) ((OkPacket) currResult).getAffectedRows();
+  }
+
+  private void executeInternal(String sql, int autoGeneratedKeys) throws SQLException {
+    checkNotClosed();
+    lock.lock();
+    try {
+      this.autoGeneratedKeys = autoGeneratedKeys;
+      String cmd = escapeTimeout(sql);
+      results =
+          con.getClient()
+              .execute(
+                  new QueryPacket(cmd, localInfileInputStream),
+                  this,
+                  fetchSize,
+                  maxRows,
+                  resultSetConcurrency,
+                  resultSetType,
+                  closeOnCompletion,
+                  false);
+    } finally {
+      localInfileInputStream = null;
+      lock.unlock();
+    }
+  }
+
+  /**
+   * Executes the given SQL statement and signals the driver that the auto-generated keys indicated
+   * in the given array should be made available for retrieval. This array contains the indexes of
+   * the columns in the target table that contain the auto-generated keys that should be made
+   * available. The driver will ignore the array if the SQL statement is not an <code>INSERT</code>
+   * statement, or an SQL statement able to return auto-generated keys (the list of such statements
+   * is vendor-specific).
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>,
+   *     <code>UPDATE</code> or <code>DELETE</code>; or an SQL statement that returns nothing, such
+   *     as a DDL statement.
+   * @param columnIndexes an array of column indexes indicating the columns that should be returned
+   *     from the inserted row
+   * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0
+   *     for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the SQL statement returns a <code>ResultSet</code> object,the
+   *     second argument supplied to this method is not an <code>int</code> array whose elements are
+   *     valid column indexes, the method is called on a <code>PreparedStatement</code> or <code>
+   *     CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @since 1.4
+   */
+  @Override
+  public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+    return executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
+  }
+
+  /**
+   * Executes the given SQL statement and signals the driver that the auto-generated keys indicated
+   * in the given array should be made available for retrieval. This array contains the names of the
+   * columns in the target table that contain the auto-generated keys that should be made available.
+   * The driver will ignore the array if the SQL statement is not an <code>INSERT</code> statement,
+   * or an SQL statement able to return auto-generated keys (the list of such statements is
+   * vendor-specific).
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>,
+   *     <code>UPDATE</code> or <code>DELETE</code>; or an SQL statement that returns nothing, such
+   *     as a DDL statement.
+   * @param columnNames an array of the names of the columns that should be returned from the
+   *     inserted row
+   * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>, or <code>DELETE
+   *     </code> statements, or 0 for SQL statements that return nothing
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the SQL statement returns a <code>ResultSet</code> object, the
+   *     second argument supplied to this method is not a <code>String</code> array whose elements
+   *     are valid column names, the method is called on a <code>PreparedStatement</code> or <code>
+   *     CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @since 1.4
+   */
+  @Override
+  public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+    return executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
+  }
+
+  /**
+   * Executes the given SQL statement, which may return multiple results, and signals the driver
+   * that any auto-generated keys should be made available for retrieval. The driver will ignore
+   * this signal if the SQL statement is not an <code>INSERT</code> statement, or an SQL statement
+   * able to return auto-generated keys (the list of such statements is vendor-specific).
+   *
+   * <p>In some (uncommon) situations, a single SQL statement may return multiple result sets and/or
+   * update counts. Normally you can ignore this unless you are (1) executing a stored procedure
+   * that you know may return multiple results or (2) you are dynamically executing an unknown SQL
+   * string.
+   *
+   * <p>The <code>execute</code> method executes an SQL statement and indicates the form of the
+   * first result. You must then use the methods <code>getResultSet</code> or <code>getUpdateCount
+   * </code> to retrieve the result, and <code>getMoreResults</code> to move to any subsequent
+   * result(s).
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql any SQL statement
+   * @param autoGeneratedKeys a constant indicating whether auto-generated keys should be made
+   *     available for retrieval using the method <code>getGeneratedKeys</code>; one of the
+   *     following constants: <code>Statement.RETURN_GENERATED_KEYS</code> or <code>
+   *     Statement.NO_GENERATED_KEYS</code>
+   * @return <code>true</code> if the first result is a <code>ResultSet</code> object; <code>false
+   *     </code> if it is an update count or there are no results
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the second parameter supplied to this method is not <code>
+   *     Statement.RETURN_GENERATED_KEYS</code> or <code>Statement.NO_GENERATED_KEYS</code>, the
+   *     method is called on a <code>PreparedStatement</code> or <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method with a
+   *     constant of Statement.RETURN_GENERATED_KEYS
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @see #getResultSet
+   * @see #getUpdateCount
+   * @see #getMoreResults
+   * @see #getGeneratedKeys
+   * @since 1.4
+   */
+  @Override
+  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+    executeInternal(sql, autoGeneratedKeys);
+
+    currResult = results.remove(0);
+    return currResult instanceof Result;
+  }
+
+  /**
+   * Build sql command to execute :
+   *
+   * <ul>
+   *   <li>Execute escape substitution if needed
+   *   <li>add query timeout prefix if server permits it
+   *   <li>add max row limit prefix if server permits it
+   * </ul>
+   *
+   * @param sql sql command
+   * @return sql command to execute
+   * @throws SQLException if fails to escape sql
+   */
+  protected String escapeTimeout(final String sql) throws SQLException {
+    String escapedSql = escape ? NativeSql.parse(sql, con.getContext()) : sql;
+    if (queryTimeout != 0 && canUseServerTimeout) {
+      if (canUseServerMaxRows && maxRows > 0) {
+        return "SET STATEMENT max_statement_time="
+            + queryTimeout
+            + ", SQL_SELECT_LIMIT="
+            + maxRows
+            + " FOR "
+            + escapedSql;
+      }
+      return "SET STATEMENT max_statement_time=" + queryTimeout + " FOR " + escapedSql;
+    }
+    if (canUseServerMaxRows && maxRows > 0) {
+      return "SET STATEMENT SQL_SELECT_LIMIT=" + maxRows + " FOR " + escapedSql;
+    }
+    return escapedSql;
+  }
+
+  /**
+   * Executes the given SQL statement, which may return multiple results, and signals the driver
+   * that the auto-generated keys indicated in the given array should be made available for
+   * retrieval. This array contains the indexes of the columns in the target table that contain the
+   * auto-generated keys that should be made available. The driver will ignore the array if the SQL
+   * statement is not an <code>INSERT</code> statement, or an SQL statement able to return
+   * auto-generated keys (the list of such statements is vendor-specific).
+   *
+   * <p>Under some (uncommon) situations, a single SQL statement may return multiple result sets
+   * and/or update counts. Normally you can ignore this unless you are (1) executing a stored
+   * procedure that you know may return multiple results or (2) you are dynamically executing an
+   * unknown SQL string.
+   *
+   * <p>The <code>execute</code> method executes an SQL statement and indicates the form of the
+   * first result. You must then use the methods <code>getResultSet</code> or <code>getUpdateCount
+   * </code> to retrieve the result, and <code>getMoreResults</code> to move to any subsequent
+   * result(s).
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql any SQL statement
+   * @param columnIndexes an array of the indexes of the columns in the inserted row that should be
+   *     made available for retrieval by a call to the method <code>getGeneratedKeys</code>
+   * @return <code>true</code> if the first result is a <code>ResultSet</code> object; <code>false
+   *     </code> if it is an update count or there are no results
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>, the elements in the <code>int</code> array passed to this method
+   *     are not valid column indexes, the method is called on a <code>PreparedStatement</code> or
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @see #getResultSet
+   * @see #getUpdateCount
+   * @see #getMoreResults
+   * @since 1.4
+   */
+  @Override
+  public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+    return execute(sql, Statement.RETURN_GENERATED_KEYS);
+  }
+
+  /**
+   * Executes the given SQL statement, which may return multiple results, and signals the driver
+   * that the auto-generated keys indicated in the given array should be made available for
+   * retrieval. This array contains the names of the columns in the target table that contain the
+   * auto-generated keys that should be made available. The driver will ignore the array if the SQL
+   * statement is not an <code>INSERT</code> statement, or an SQL statement able to return
+   * auto-generated keys (the list of such statements is vendor-specific).
+   *
+   * <p>In some (uncommon) situations, a single SQL statement may return multiple result sets and/or
+   * update counts. Normally you can ignore this unless you are (1) executing a stored procedure
+   * that you know may return multiple results or (2) you are dynamically executing an unknown SQL
+   * string.
+   *
+   * <p>The <code>execute</code> method executes an SQL statement and indicates the form of the
+   * first result. You must then use the methods <code>getResultSet</code> or <code>getUpdateCount
+   * </code> to retrieve the result, and <code>getMoreResults</code> to move to any subsequent
+   * result(s).
+   *
+   * <p><strong>Note:</strong>This method cannot be called on a <code>PreparedStatement</code> or
+   * <code>CallableStatement</code>.
+   *
+   * @param sql any SQL statement
+   * @param columnNames an array of the names of the columns in the inserted row that should be made
+   *     available for retrieval by a call to the method <code>getGeneratedKeys</code>
+   * @return <code>true</code> if the next result is a <code>ResultSet</code> object; <code>false
+   *     </code> if it is an update count or there are no more results
+   * @throws SQLException if a database access error occurs, this method is called on a closed
+   *     <code>Statement</code>,the elements of the <code>String</code> array passed to this method
+   *     are not valid column names, the method is called on a <code>PreparedStatement</code> or
+   *     <code>CallableStatement</code>
+   * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
+   * @throws SQLTimeoutException when the driver has determined that the timeout value that was
+   *     specified by the {@code setQueryTimeout} method has been exceeded and has at least
+   *     attempted to cancel the currently running {@code Statement}
+   * @see #getResultSet
+   * @see #getUpdateCount
+   * @see #getMoreResults
+   * @see #getGeneratedKeys
+   * @since 1.4
+   */
+  @Override
+  public boolean execute(String sql, String[] columnNames) throws SQLException {
+    return execute(sql, Statement.RETURN_GENERATED_KEYS);
+  }
+
+  /**
+   * Retrieves the result set holdability for <code>ResultSet</code> objects generated by this
+   * <code>Statement</code> object.
+   *
+   * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or <code>
+   *     ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
+   * @since 1.4
+   */
+  @Override
+  public int getResultSetHoldability() {
+    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+  /**
+   * Retrieves whether this <code>Statement</code> object has been closed. A <code>Statement</code>
+   * is closed if the method close has been called on it, or if it is automatically closed.
+   *
+   * @return true if this <code>Statement</code> object is closed; false if it is still open
+   */
+  @Override
+  public boolean isClosed() {
+    return closed;
+  }
+
+  /**
+   * Returns a value indicating whether the <code>Statement</code> is poolable or not.
+   *
+   * @return <code>true</code> if the <code>Statement</code> is poolable; <code>false</code>
+   *     otherwise
+   * @throws SQLException if this method is called on a closed <code>Statement</code>
+   * @see java.sql.Statement#setPoolable(boolean) setPoolable(boolean)
+   */
+  @Override
+  public boolean isPoolable() throws SQLException {
+    checkNotClosed();
+    return false;
+  }
+
+  /**
+   * Requests that a <code>Statement</code> be pooled or not pooled. The value specified is a hint
+   * to the statement pool implementation indicating whether the application wants the statement to
+   * be pooled. It is up to the statement pool manager whether the hint is used.
+   *
+   * <p>The poolable value of a statement is applicable to both internal statement caches
+   * implemented by the driver and external statement caches implemented by application servers and
+   * other applications.
+   *
+   * <p>By default, a <code>Statement</code> is not poolable when created, and a <code>
+   * PreparedStatement</code> and <code>CallableStatement</code> are poolable when created.
+   *
+   * @param poolable requests that the statement be pooled if true and that the statement not be
+   *     pooled if false
+   * @throws SQLException if this method is called on a closed <code>Statement</code>
+   */
+  @Override
+  public void setPoolable(boolean poolable) throws SQLException {
+    checkNotClosed();
+  }
+
+  /**
+   * Specifies that this {@code Statement} will be closed when all its dependent result sets are
+   * closed. If execution of the {@code Statement} does not produce any result sets, this method has
+   * no effect.
+   *
+   * <p><strong>Note:</strong> Multiple calls to {@code closeOnCompletion} do not toggle the effect
+   * on this {@code Statement}. However, a call to {@code closeOnCompletion} does affect both the
+   * subsequent execution of statements, and statements that currently have open, dependent, result
+   * sets.
+   *
+   * @throws SQLException if this method is called on a closed {@code Statement}
+   */
+  @Override
+  public void closeOnCompletion() throws SQLException {
+    checkNotClosed();
+    this.closeOnCompletion = true;
+  }
+
+  /**
+   * Returns a value indicating whether this {@code Statement} will be closed when all its dependent
+   * result sets are closed.
+   *
+   * @return {@code true} if the {@code Statement} will be closed when all of its dependent result
+   *     sets are closed; {@code false} otherwise
+   * @throws SQLException if this method is called on a closed {@code Statement}
+   */
+  @Override
+  public boolean isCloseOnCompletion() throws SQLException {
+    checkNotClosed();
+    return closeOnCompletion;
+  }
+
+  /**
+   * Returns an object that implements the given interface to allow access to non-standard methods,
+   * or standard methods not exposed by the proxy.
+   *
+   * <p>If the receiver implements the interface then the result is the receiver or a proxy for the
+   * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the
+   * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of
+   * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If
+   * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException
+   * </code> is thrown.
+   *
+   * @param iface A Class defining an interface that the result must implement.
+   * @return an object that implements the interface. Maybe a proxy for the actual implementing
+   *     object.
+   * @throws SQLException If no object found that implements the interface
+   */
+  @Override
+  @SuppressWarnings("unchecked")
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return (T) this;
+    }
+    throw exceptionFactory()
+        .create("The receiver is not a wrapper and does not implement the interface", "42000");
+  }
+
+  /**
+   * Returns true if this either implements the interface argument or is directly or indirectly a
+   * wrapper for an object that does. Returns false otherwise. If this implements the interface then
+   * return true, else if this is a wrapper then return the result of recursively calling <code>
+   * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not
+   * a wrapper, return false. This method should be implemented as a low-cost operation compared to
+   * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>
+   * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same
+   * argument should succeed.
+   *
+   * @param iface a Class defining an interface.
+   * @return true if this implements the interface or directly or indirectly wraps an object that
+   *     does.
+   */
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    if (iface == null) return false;
+    return iface.isInstance(this);
+  }
+
+  /**
+   * Check if statement is closed, and throw exception if so.
+   *
+   * @throws SQLException if statement close
+   */
+  protected void checkNotClosed() throws SQLException {
+    if (closed) {
+      throw exceptionFactory().create("Cannot do an operation on a closed statement");
+    }
+  }
+
+  /**
+   * Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL
+   * statement that returns nothing, such as an SQL DDL statement. This method should be used when
+   * the returned row count may exceed Integer.MAX_VALUE.
+   *
+   * @param sql sql command
+   * @return update counts
+   * @throws SQLException if any error occur during execution
+   */
+  @Override
+  public long executeLargeUpdate(String sql) throws SQLException {
+    return executeLargeUpdate(sql, Statement.NO_GENERATED_KEYS);
+  }
+
+  /**
+   * Identical to executeLargeUpdate(String sql), with a flag that indicate that autoGeneratedKeys
+   * (primary key fields with "auto_increment") generated id's must be retrieved.
+   *
+   * <p>Those id's will be available using getGeneratedKeys() method.
+   *
+   * @param sql sql command
+   * @param autoGeneratedKeys a flag indicating whether auto-generated keys should be made available
+   *     for retrieval; one of the following constants: Statement.RETURN_GENERATED_KEYS
+   *     Statement.NO_GENERATED_KEYS
+   * @return update counts
+   * @throws SQLException if any error occur during execution
+   */
+  @Override
+  public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+    executeInternal(sql, autoGeneratedKeys);
+    currResult = results.remove(0);
+    if (currResult instanceof Result) {
+      throw exceptionFactory()
+          .create("the given SQL statement produces an unexpected ResultSet object", "HY000");
+    }
+    return ((OkPacket) currResult).getAffectedRows();
+  }
+
+  /**
+   * Identical to executeLargeUpdate(String sql, int autoGeneratedKeys) with autoGeneratedKeys =
+   * Statement.RETURN_GENERATED_KEYS set.
+   *
+   * @param sql sql command
+   * @param columnIndexes column Indexes
+   * @return update counts
+   * @throws SQLException if any error occur during execution
+   */
+  @Override
+  public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
+    return executeLargeUpdate(sql, java.sql.Statement.RETURN_GENERATED_KEYS);
+  }
+
+  /**
+   * Identical to executeLargeUpdate(String sql, int autoGeneratedKeys) with autoGeneratedKeys =
+   * Statement.RETURN_GENERATED_KEYS set.
+   *
+   * @param sql sql command
+   * @param columnNames columns names
+   * @return update counts
+   * @throws SQLException if any error occur during execution
+   */
+  @Override
+  public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
+    return executeLargeUpdate(sql, java.sql.Statement.RETURN_GENERATED_KEYS);
+  }
+
+  /**
+   * Retrieves the maximum number of rows that a ResultSet object produced by this Statement object
+   * can contain. If this limit is exceeded, the excess rows are silently dropped.
+   *
+   * @throws SQLException if this method is called on a closed Statement
+   * @return the current maximum number of rows for a ResultSet object produced by this Statement
+   *     object; zero means there is no limit
+   */
+  @Override
+  public long getLargeMaxRows() throws SQLException {
+    checkNotClosed();
+    return maxRows;
+  }
+
+  /**
+   * Sets the limit for the maximum number of rows that any ResultSet object generated by this
+   * Statement object can contain to the given number. If the limit is exceeded, the excess rows are
+   * silently dropped.
+   *
+   * @param max the new max rows limit; zero means there is no limit
+   * @throws SQLException if the condition max &gt;= 0 is not satisfied
+   */
+  @Override
+  public void setLargeMaxRows(long max) throws SQLException {
+    checkNotClosed();
+    if (max < 0) {
+      throw exceptionFactory().create("max rows cannot be negative : asked for " + max, "42000");
+    }
+    maxRows = max;
+  }
+
+  /**
+   * Retrieves the current result as an update count; if the result is a ResultSet object or there
+   * are no more results, -1 is returned.
+   *
+   * @throws SQLException if this method is called on a closed Statement
+   * @return last update count
+   */
+  @Override
+  public long getLargeUpdateCount() throws SQLException {
+    checkNotClosed();
+    if (currResult instanceof OkPacket) {
+      return (int) ((OkPacket) currResult).getAffectedRows();
+    }
+    return -1;
+  }
+
+  /**
+   * Execute batch, like executeBatch(), with returning results with long[]. For when row count may
+   * exceed Integer.MAX_VALUE.
+   *
+   * @return an array of update counts (one element for each command in the batch)
+   * @throws SQLException if a database error occur.
+   */
+  @Override
+  public long[] executeLargeBatch() throws SQLException {
+    checkNotClosed();
+    if (batchQueries == null || batchQueries.isEmpty()) return new long[0];
+
+    lock.lock();
+    try {
+      // ensure pipelining is possible (no LOAD DATA/XML INFILE commands)
+      boolean possibleLoadLocal = con.getContext().hasClientCapability(LOCAL_FILES);
+      if (possibleLoadLocal) {
+        for (int i = 0; i < batchQueries.size(); i++) {
+          String sql = batchQueries.get(i).toUpperCase(Locale.ROOT);
+          if (sql.contains(" LOCAL ") && sql.contains("LOAD") && sql.contains(" INFILE")) {
+            break;
+          }
+        }
+        possibleLoadLocal = false;
+      }
+
+      List<Completion> res =
+          possibleLoadLocal ? executeInternalBatchStandard() : executeInternalBatchPipeline();
+
+      results = res;
+      long[] updates = new long[res.size()];
+      for (int i = 0; i < res.size(); i++) {
+        updates[i] = ((OkPacket) res.get(i)).getAffectedRows();
+      }
+      currResult = results.remove(0);
+      batchQueries.clear();
+      return updates;
+
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  /**
+   * Execute batch pipelining commands (sending all client message, then reading results) (batches
+   * cannot contain results-set, so cannot fill receiving socket buffer while sending buffer is
+   * full)
+   *
+   * @return results
+   * @throws SQLException if any error occurs
+   */
+  public List<Completion> executeInternalBatchPipeline() throws SQLException {
+    QueryPacket[] packets = new QueryPacket[batchQueries.size()];
+    for (int i = 0; i < batchQueries.size(); i++) {
+      String sql = batchQueries.get(i);
+      packets[i] = new QueryPacket(sql);
+    }
+    return con.getClient()
+        .executePipeline(
+            packets,
+            this,
+            0,
+            0L,
+            ResultSet.CONCUR_READ_ONLY,
+            ResultSet.TYPE_FORWARD_ONLY,
+            closeOnCompletion,
+            false);
+  }
+
+  /**
+   * basic implementation Send batch query per query.
+   *
+   * @return results
+   * @throws SQLException if any error occurs
+   */
+  public List<Completion> executeInternalBatchStandard() throws SQLException {
+    List<Completion> results = new ArrayList<>();
+    try {
+      for (String batchQuery : batchQueries) {
+        results.addAll(
+            con.getClient()
+                .execute(
+                    new QueryPacket(batchQuery, localInfileInputStream),
+                    this,
+                    0,
+                    0L,
+                    ResultSet.CONCUR_READ_ONLY,
+                    ResultSet.TYPE_FORWARD_ONLY,
+                    closeOnCompletion,
+                    false));
+      }
+      return results;
+    } catch (SQLException sqle) {
+      int[] updateCounts = new int[batchQueries.size()];
+      for (int i = 0; i < Math.min(results.size(), updateCounts.length); i++) {
+        Completion completion = results.get(i);
+        updateCounts[i] =
+            completion instanceof OkPacket ? (int) ((OkPacket) completion).getAffectedRows() : 0;
+      }
+      throw new BatchUpdateException(
+          sqle.getMessage(), sqle.getSQLState(), sqle.getErrorCode(), updateCounts, sqle);
+    } finally {
+      localInfileInputStream = null;
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/TransactionIsolation.java b/src/main/java/org/mariadb/jdbc/TransactionIsolation.java
new file mode 100644
index 0000000..37b219f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/TransactionIsolation.java
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc;
+
+import java.sql.Connection;
+
+/** Transaction isolation enumeration */
+public enum TransactionIsolation {
+  /**
+   * dirty reads and non-repeatable reads are prevented; phantom reads can occur. This level
+   * prohibits a transaction from reading a row with uncommitted changes in it, and it also
+   * prohibits the situation where one transaction reads a row, a second transaction alters the row,
+   * and the first transaction rereads the row, getting different values the second time (a
+   * "non-repeatable read").
+   */
+  REPEATABLE_READ("REPEATABLE-READ", java.sql.Connection.TRANSACTION_REPEATABLE_READ),
+  /**
+   * dirty reads are prevented; non-repeatable reads and phantom reads can occur. This level only
+   * prohibits a transaction from reading a row with uncommitted changes in it.
+   */
+  READ_COMMITTED("READ-COMMITTED", Connection.TRANSACTION_READ_COMMITTED),
+  /**
+   * dirty reads, non-repeatable reads and phantom reads can occur. This level allows a row changed
+   * by one transaction to be read by another transaction before any changes in that row have been
+   * committed (a "dirty read"). If any of the changes are rolled back, the second transaction will
+   * have retrieved an invalid row.
+   */
+  READ_UNCOMMITTED("READ-UNCOMMITTED", Connection.TRANSACTION_READ_UNCOMMITTED),
+  /**
+   * dirty reads, non-repeatable reads and phantom reads are prevented. This level includes the
+   * prohibitions in TRANSACTION_REPEATABLE_READ and further prohibits the situation where one
+   * transaction reads all rows that satisfy a WHERE condition, a second transaction inserts a row
+   * that satisfies that WHERE condition, and the first transaction rereads for the same condition,
+   * retrieving the additional "phantom" row in the second read.
+   */
+  SERIALIZABLE("SERIALIZABLE", Connection.TRANSACTION_SERIALIZABLE);
+
+  private final String value;
+  private final int level;
+
+  TransactionIsolation(String value, int level) {
+    this.value = value;
+    this.level = level;
+  }
+
+  /**
+   * Get transaction isolation command
+   *
+   * @return transaction isolation command
+   */
+  public String getValue() {
+    return value;
+  }
+
+  /**
+   * Get transaction isolation level
+   *
+   * @return transaction isolation level
+   */
+  public int getLevel() {
+    return level;
+  }
+
+  /**
+   * Get TransactionIsolation from value
+   *
+   * @param value value
+   * @return transaction isolation
+   */
+  public static TransactionIsolation from(String value) {
+    for (TransactionIsolation transactionIsolation : values()) {
+      if (transactionIsolation
+          .value
+          .replaceAll("[ \\-_]", "")
+          .equalsIgnoreCase(value.replaceAll("[ \\-_]", ""))) {
+        return transactionIsolation;
+      }
+    }
+    throw new IllegalArgumentException(
+        String.format("Wrong argument value '%s' for TransactionIsolation", value));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/Client.java b/src/main/java/org/mariadb/jdbc/client/Client.java
new file mode 100644
index 0000000..95f535b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/Client.java
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.concurrent.Executor;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/** Client interface */
+public interface Client extends AutoCloseable {
+
+  /**
+   * Send client message and read result
+   *
+   * @param message client message
+   * @param canRedo can client message be redone in case of failover
+   * @return results
+   * @throws SQLException if execution fails
+   */
+  List<Completion> execute(ClientMessage message, boolean canRedo) throws SQLException;
+
+  /**
+   * Send client message and read result
+   *
+   * @param message client message
+   * @param stmt statement
+   * @param canRedo can client message be redone in case of failover
+   * @return results
+   * @throws SQLException if execution fails
+   */
+  List<Completion> execute(ClientMessage message, org.mariadb.jdbc.Statement stmt, boolean canRedo)
+      throws SQLException;
+
+  /**
+   * Send client message and read result
+   *
+   * @param message client message
+   * @param stmt statement
+   * @param fetchSize fetch size
+   * @param maxRows maximum number of rows. 0 = all
+   * @param resultSetConcurrency concurrency
+   * @param resultSetType result-set type
+   * @param closeOnCompletion close statement on completion
+   * @param canRedo can client message be redone in case of failover
+   * @return results
+   * @throws SQLException if any error occurs
+   */
+  List<Completion> execute(
+      ClientMessage message,
+      org.mariadb.jdbc.Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException;
+
+  /**
+   * Send client messages pipelining and read result
+   *
+   * @param messages client message
+   * @param stmt statement
+   * @param fetchSize fetch size
+   * @param maxRows maximum number of rows. 0 = all
+   * @param resultSetConcurrency concurrency
+   * @param resultSetType result-set type
+   * @param closeOnCompletion close statement on completion
+   * @param canRedo can client message be redone in case of failover
+   * @return results
+   * @throws SQLException if any error occurs
+   */
+  List<Completion> executePipeline(
+      ClientMessage[] messages,
+      org.mariadb.jdbc.Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException;
+
+  /**
+   * Read results
+   *
+   * @param completions List that will have the new results
+   * @param fetchSize fetch size
+   * @param maxRows maximum number of rows. 0 = all
+   * @param resultSetConcurrency concurrency
+   * @param resultSetType result-set type
+   * @param closeOnCompletion close statement on completion
+   * @throws SQLException if any error occurs
+   */
+  void readStreamingResults(
+      List<Completion> completions,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion)
+      throws SQLException;
+
+  /**
+   * Close prepare command
+   *
+   * @param prepare prepare command
+   * @throws SQLException if any error occurs
+   */
+  void closePrepare(Prepare prepare) throws SQLException;
+
+  /**
+   * Abort current connection
+   *
+   * @param executor executor
+   * @throws SQLException if any error occurs
+   */
+  void abort(Executor executor) throws SQLException;
+
+  /**
+   * Close client
+   *
+   * @throws SQLException if any error occurs
+   */
+  void close() throws SQLException;
+
+  /**
+   * Switch to a writer/read-only connection, no effet on mono-connection
+   *
+   * @param readOnly must use read-only connection
+   * @throws SQLException if any error occurs
+   */
+  void setReadOnly(boolean readOnly) throws SQLException;
+
+  /**
+   * get socket timeout
+   *
+   * @return socket timeout
+   */
+  int getSocketTimeout();
+
+  /**
+   * Set socket timeout
+   *
+   * @param milliseconds timeout
+   * @throws SQLException if any error occurs
+   */
+  void setSocketTimeout(int milliseconds) throws SQLException;
+
+  /**
+   * Is client closed
+   *
+   * @return close flag
+   */
+  boolean isClosed();
+
+  /** Reset connection */
+  void reset();
+
+  /**
+   * is current client writer or read-only
+   *
+   * @return is primary
+   */
+  boolean isPrimary();
+
+  /**
+   * Get connection context
+   *
+   * @return connection context
+   */
+  Context getContext();
+
+  /**
+   * Get connection exception factory
+   *
+   * @return connection exception factory
+   */
+  ExceptionFactory getExceptionFactory();
+
+  /**
+   * Get connection host
+   *
+   * @return connection host
+   */
+  HostAddress getHostAddress();
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/Column.java b/src/main/java/org/mariadb/jdbc/client/Column.java
new file mode 100644
index 0000000..8032aa8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/Column.java
@@ -0,0 +1,120 @@
+package org.mariadb.jdbc.client;
+
+public interface Column {
+
+  /**
+   * get column schema
+   *
+   * @return column schema
+   */
+  String getSchema();
+
+  /**
+   * retrieve table alias if any
+   *
+   * @return table alias
+   */
+  String getTableAlias();
+
+  /**
+   * retrieve table name if any
+   *
+   * @return table name
+   */
+  String getTable();
+
+  /**
+   * retrieve column alias if any
+   *
+   * @return column alias
+   */
+  String getColumnAlias();
+
+  /**
+   * retrieve column name if any
+   *
+   * @return column name
+   */
+  String getColumnName();
+
+  /**
+   * column maximum length if known
+   *
+   * @return column maximum length
+   */
+  long getColumnLength();
+
+  /**
+   * server data type
+   *
+   * @return server data type
+   */
+  DataType getType();
+
+  /**
+   * get number of decimal
+   *
+   * @return number of decimal
+   */
+  byte getDecimals();
+
+  /**
+   * Is column signed (for number only)
+   *
+   * @return is signed
+   */
+  boolean isSigned();
+
+  /**
+   * get display size
+   *
+   * @return display sier
+   */
+  int getDisplaySize();
+
+  /**
+   * Is column a primary key
+   *
+   * @return is a primary key
+   */
+  boolean isPrimaryKey();
+
+  /**
+   * Column autoincrement
+   *
+   * @return true if column auto-increment
+   */
+  boolean isAutoIncrement();
+
+  /**
+   * Column has a default value
+   *
+   * @return indicate if has a default value
+   */
+  boolean hasDefault();
+
+  /**
+   * indicate if column is of binary type. doesn't use flag BINARY filter, because char binary and
+   * varchar binary are not binary (handle like string), but have binary flag
+   *
+   * @return is column type binary
+   */
+  boolean isBinary();
+
+  /**
+   * Retrieve metadata flag
+   *
+   * @return metadata flag
+   */
+  int getFlags();
+
+  /**
+   * retrieve extended metadata name if any
+   *
+   * @return extended metadata name
+   */
+  String getExtTypeName();
+
+  /** Use column alias as name */
+  void useAliasAsName();
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/ColumnDecoder.java b/src/main/java/org/mariadb/jdbc/client/ColumnDecoder.java
new file mode 100644
index 0000000..33e1465
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/ColumnDecoder.java
@@ -0,0 +1,425 @@
+package org.mariadb.jdbc.client;
+
+import java.nio.charset.StandardCharsets;
+import java.sql.Date;
+import java.sql.SQLDataException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.column.UuidColumn;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.util.constants.ColumnFlags;
+
+public interface ColumnDecoder extends Column {
+
+  /**
+   * Returns default class name depending on server column datatype
+   *
+   * @param conf configuration
+   * @return default class name
+   */
+  String defaultClassname(Configuration conf);
+
+  /**
+   * Returns default java.sql.Types depending on server column datatype
+   *
+   * @param conf configuration
+   * @return default java.sql.Types
+   */
+  int getColumnType(Configuration conf);
+
+  /**
+   * Returns server column datatype
+   *
+   * @param conf configuration
+   * @return default server column datatype
+   */
+  String getColumnTypeName(Configuration conf);
+
+  /**
+   * Return decimal precision.
+   *
+   * @return decimal precision
+   */
+  default int getPrecision() {
+    return (int) getColumnLength();
+  }
+
+  /**
+   * Return default Object text encoded
+   *
+   * @param conf configuration
+   * @param buf row buffer
+   * @param length data length
+   * @return default Object
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Object getDefaultText(final Configuration conf, final ReadableByteBuf buf, final int length)
+      throws SQLDataException;
+
+  /**
+   * Return default Object binary encoded
+   *
+   * @param conf configuration
+   * @param buf row buffer
+   * @param length data length
+   * @return default Object
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Object getDefaultBinary(final Configuration conf, final ReadableByteBuf buf, final int length)
+      throws SQLDataException;
+
+  /**
+   * Return String text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return String value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  String decodeStringText(final ReadableByteBuf buf, final int length, final Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Return String binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return String value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  String decodeStringBinary(final ReadableByteBuf buf, final int length, final Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Return byte text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return byte value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  byte decodeByteText(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Return byte binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return byte value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  byte decodeByteBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Return date text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return date value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Date decodeDateText(final ReadableByteBuf buf, final int length, Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Return date binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return date value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Date decodeDateBinary(final ReadableByteBuf buf, final int length, Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Return time text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return time value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Time decodeTimeText(final ReadableByteBuf buf, final int length, Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Return time binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return time value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Time decodeTimeBinary(final ReadableByteBuf buf, final int length, Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Return timestamp text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return timestamp value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Timestamp decodeTimestampText(final ReadableByteBuf buf, final int length, Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Return timestamp binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @param cal calendar
+   * @return timestamp value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  Timestamp decodeTimestampBinary(final ReadableByteBuf buf, final int length, Calendar cal)
+      throws SQLDataException;
+  /**
+   * Return boolean text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return boolean value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  boolean decodeBooleanText(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Parse boolean binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return boolean value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  boolean decodeBooleanBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
+  /**
+   * Parse short text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return short value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  short decodeShortText(final ReadableByteBuf buf, final int length) throws SQLDataException;
+  /**
+   * Parse short binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return short value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  short decodeShortBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
+  /**
+   * Parse int text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return int value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  int decodeIntText(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Parse int binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return int value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  int decodeIntBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Parse long text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return long value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  long decodeLongText(final ReadableByteBuf buf, final int length) throws SQLDataException;
+  /**
+   * Parse long binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return long value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  long decodeLongBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Parse float text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return float value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  float decodeFloatText(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Parse float binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return float value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  float decodeFloatBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Parse double text encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return double value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  double decodeDoubleText(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Parse double binary encoded value
+   *
+   * @param buf row buffer
+   * @param length data length
+   * @return double value
+   * @throws SQLDataException if any decoding error occurs
+   */
+  double decodeDoubleBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
+
+  /**
+   * Decode Column from mysql packet
+   *
+   * @param buf packet
+   * @param extendedInfo is extended datatype information capability enable
+   * @return column
+   */
+  static ColumnDecoder decode(ReadableByteBuf buf, boolean extendedInfo) {
+    // skip first strings
+    int[] stringPos = new int[5];
+    stringPos[0] = buf.skipIdentifier(); // schema pos
+    stringPos[1] = buf.skipIdentifier(); // table alias pos
+    stringPos[2] = buf.skipIdentifier(); // table pos
+    stringPos[3] = buf.skipIdentifier(); // column alias pos
+    stringPos[4] = buf.skipIdentifier(); // column pos
+    buf.skipIdentifier();
+
+    String extTypeName = null;
+    String extTypeFormat = null;
+    if (extendedInfo) {
+      // fast skipping extended info (usually not set)
+      if (buf.readByte() != 0) {
+        // revert position, because has extended info.
+        buf.pos(buf.pos() - 1);
+
+        ReadableByteBuf subPacket = buf.readLengthBuffer();
+        while (subPacket.readableBytes() > 0) {
+          switch (subPacket.readByte()) {
+            case 0:
+              extTypeName = subPacket.readAscii(subPacket.readLength());
+              break;
+            case 1:
+              extTypeFormat = subPacket.readAscii(subPacket.readLength());
+              break;
+            default: // skip data
+              subPacket.skip(subPacket.readLength());
+              break;
+          }
+        }
+      }
+    }
+
+    buf.skip(); // skip length always 0x0c
+    short charset = buf.readShort();
+    int length = buf.readInt();
+    DataType dataType = DataType.of(buf.readUnsignedByte());
+    int flags = buf.readUnsignedShort();
+    byte decimals = buf.readByte();
+    DataType.ColumnConstructor constructor =
+        (extTypeName != null && extTypeName.equals("uuid"))
+            ? UuidColumn::new
+            : (flags & ColumnFlags.UNSIGNED) == 0
+                ? dataType.getColumnConstructor()
+                : dataType.getUnsignedColumnConstructor();
+    return constructor.create(
+        buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  /**
+   * Create fake MySQL column definition packet with indicated datatype
+   *
+   * @param name column name
+   * @param type data type
+   * @param flags column flags
+   * @return Column
+   */
+  static ColumnDecoder create(String name, DataType type, int flags) {
+    byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
+    byte[] arr = new byte[9 + 2 * nameBytes.length];
+    arr[0] = 3;
+    arr[1] = 'D';
+    arr[2] = 'E';
+    arr[3] = 'F';
+
+    int[] stringPos = new int[5];
+    stringPos[0] = 4; // schema pos
+    stringPos[1] = 5; // table alias pos
+    stringPos[2] = 6; // table pos
+
+    // lenenc_str     name
+    // lenenc_str     org_name
+    int pos = 7;
+    for (int i = 0; i < 2; i++) {
+      stringPos[i + 3] = pos;
+      arr[pos++] = (byte) nameBytes.length;
+      System.arraycopy(nameBytes, 0, arr, pos, nameBytes.length);
+      pos += nameBytes.length;
+    }
+    int len;
+
+    /* Sensible predefined length - since we're dealing with I_S here, most char fields are 64 char long */
+    switch (type) {
+      case VARCHAR:
+      case VARSTRING:
+        len = 64 * 3; /* 3 bytes per UTF8 char */
+        break;
+      case SMALLINT:
+        len = 5;
+        break;
+      case NULL:
+        len = 0;
+        break;
+      default:
+        len = 1;
+        break;
+    }
+    DataType.ColumnConstructor constructor =
+        (flags & ColumnFlags.UNSIGNED) == 0
+            ? type.getColumnConstructor()
+            : type.getUnsignedColumnConstructor();
+    return constructor.create(
+        new StandardReadableByteBuf(arr, arr.length),
+        33,
+        len,
+        type,
+        (byte) 0,
+        flags,
+        stringPos,
+        null,
+        null);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/Completion.java b/src/main/java/org/mariadb/jdbc/client/Completion.java
new file mode 100644
index 0000000..678b19d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/Completion.java
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client;
+
+import org.mariadb.jdbc.message.ServerMessage;
+
+public interface Completion extends ServerMessage {}
diff --git a/src/main/java/org/mariadb/jdbc/client/Context.java b/src/main/java/org/mariadb/jdbc/client/Context.java
new file mode 100644
index 0000000..59c019e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/Context.java
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client;
+
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.export.ExceptionFactory;
+
+public interface Context {
+
+  /**
+   * return current thread id
+   *
+   * @return current server thread id
+   */
+  long getThreadId();
+
+  /**
+   * Get connection initial seed
+   *
+   * @return initial seed
+   */
+  byte[] getSeed();
+
+  /**
+   * has server capability
+   *
+   * @param flag capability to check
+   * @return true if server has capability
+   */
+  boolean hasServerCapability(long flag);
+
+  /**
+   * has client capability
+   *
+   * @param flag capability to check
+   * @return true if client has capability
+   */
+  boolean hasClientCapability(long flag);
+
+  /**
+   * Does server and client permit pipeline
+   *
+   * @return true if permitted
+   */
+  boolean permitPipeline();
+
+  /**
+   * Get server connection state
+   *
+   * @return server status
+   */
+  int getServerStatus();
+
+  /**
+   * Set server connection state
+   *
+   * @param serverStatus server status
+   */
+  void setServerStatus(int serverStatus);
+
+  /**
+   * Get current connection database
+   *
+   * @return database
+   */
+  String getDatabase();
+
+  /**
+   * set current database context
+   *
+   * @param database database
+   */
+  void setDatabase(String database);
+
+  /**
+   * Retrieve server version information
+   *
+   * @return server version
+   */
+  ServerVersion getVersion();
+
+  /**
+   * does protocol remove EOF in exchanges
+   *
+   * @return if EOF packet are deprecated
+   */
+  boolean isEofDeprecated();
+
+  /**
+   * Can server skip prepared statement metadata
+   *
+   * @return true if possible
+   */
+  boolean canSkipMeta();
+
+  /**
+   * Does server metadata exchange extended information
+   *
+   * @return use metadata extended information
+   */
+  boolean isExtendedInfo();
+
+  /**
+   * has server warnings
+   *
+   * @return has warnings
+   */
+  int getWarning();
+
+  /**
+   * set server state warning number
+   *
+   * @param warning warning number
+   */
+  void setWarning(int warning);
+
+  /**
+   * Get connection exception factory
+   *
+   * @return exception factory
+   */
+  ExceptionFactory getExceptionFactory();
+
+  /**
+   * Get connection configuration
+   *
+   * @return configuration
+   */
+  Configuration getConf();
+
+  /**
+   * Get connection transaction isolation level
+   *
+   * @return connection transaction isolation level
+   */
+  int getTransactionIsolationLevel();
+
+  /**
+   * Set current connection transaction isolation level
+   *
+   * @param transactionIsolationLevel new connection transaction isolation level
+   */
+  void setTransactionIsolationLevel(int transactionIsolationLevel);
+
+  /**
+   * get LRU prepare cache object
+   *
+   * @return prepare cache
+   */
+  PrepareCache getPrepareCache();
+
+  /** Reset prepare cache (after a failover) */
+  void resetPrepareCache();
+
+  /**
+   * return connection current state change flag
+   *
+   * @return connection current state change flag
+   */
+  int getStateFlag();
+
+  /** reset connection state change flag */
+  void resetStateFlag();
+
+  /**
+   * Indicate connection state (for pooling)
+   *
+   * @param state indicate that some connection state has changed
+   */
+  void addStateFlag(int state);
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/DataType.java b/src/main/java/org/mariadb/jdbc/client/DataType.java
new file mode 100644
index 0000000..4b5c5a2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/DataType.java
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client;
+
+import org.mariadb.jdbc.client.column.*;
+
+public enum DataType {
+  OLDDECIMAL(0, BigDecimalColumn::new, BigDecimalColumn::new),
+  TINYINT(1, SignedTinyIntColumn::new, UnsignedTinyIntColumn::new),
+  SMALLINT(2, SignedSmallIntColumn::new, UnsignedSmallIntColumn::new),
+  INTEGER(3, SignedIntColumn::new, UnsignedIntColumn::new),
+  FLOAT(4, FloatColumn::new, FloatColumn::new),
+  DOUBLE(5, DoubleColumn::new, DoubleColumn::new),
+  NULL(6, StringColumn::new, StringColumn::new),
+  TIMESTAMP(7, TimestampColumn::new, TimestampColumn::new),
+  BIGINT(8, SignedBigIntColumn::new, UnsignedBigIntColumn::new),
+  MEDIUMINT(9, SignedMediumIntColumn::new, UnsignedMediumIntColumn::new),
+  DATE(10, DateColumn::new, DateColumn::new),
+  TIME(11, TimeColumn::new, TimeColumn::new),
+  DATETIME(12, TimestampColumn::new, TimestampColumn::new),
+  YEAR(13, YearColumn::new, YearColumn::new),
+  NEWDATE(14, DateColumn::new, DateColumn::new),
+  VARCHAR(15, StringColumn::new, StringColumn::new),
+  BIT(16, BitColumn::new, BitColumn::new),
+  JSON(245, JsonColumn::new, JsonColumn::new),
+  DECIMAL(246, BigDecimalColumn::new, BigDecimalColumn::new),
+  ENUM(247, StringColumn::new, StringColumn::new),
+  SET(248, StringColumn::new, StringColumn::new),
+  TINYBLOB(249, BlobColumn::new, BlobColumn::new),
+  MEDIUMBLOB(250, BlobColumn::new, BlobColumn::new),
+  LONGBLOB(251, BlobColumn::new, BlobColumn::new),
+  BLOB(252, BlobColumn::new, BlobColumn::new),
+  VARSTRING(253, StringColumn::new, StringColumn::new),
+  STRING(254, StringColumn::new, StringColumn::new),
+  GEOMETRY(255, GeometryColumn::new, GeometryColumn::new);
+
+  static final DataType[] typeMap;
+
+  static {
+    typeMap = new DataType[256];
+    for (DataType v : values()) {
+      typeMap[v.mariadbType] = v;
+    }
+  }
+
+  private final int mariadbType;
+  private final ColumnConstructor columnConstructor;
+  private final ColumnConstructor unsignedColumnConstructor;
+
+  DataType(
+      int mariadbType,
+      ColumnConstructor columnConstructor,
+      ColumnConstructor unsignedColumnConstructor) {
+    this.mariadbType = mariadbType;
+    this.columnConstructor = columnConstructor;
+    this.unsignedColumnConstructor = unsignedColumnConstructor;
+  }
+
+  public int get() {
+    return mariadbType;
+  }
+
+  public static DataType of(int typeValue) {
+    return typeMap[typeValue];
+  }
+
+  public ColumnConstructor getColumnConstructor() {
+    return columnConstructor;
+  }
+
+  public ColumnConstructor getUnsignedColumnConstructor() {
+    return unsignedColumnConstructor;
+  }
+
+  @FunctionalInterface
+  public interface ColumnConstructor {
+
+    ColumnDecoder create(
+        ReadableByteBuf buf,
+        int charset,
+        long length,
+        DataType dataType,
+        byte decimals,
+        int flags,
+        int[] stringPos,
+        String extTypeName,
+        String extTypeFormat);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/PrepareCache.java b/src/main/java/org/mariadb/jdbc/client/PrepareCache.java
new file mode 100644
index 0000000..4b7af9f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/PrepareCache.java
@@ -0,0 +1,30 @@
+package org.mariadb.jdbc.client;
+
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.export.Prepare;
+
+/** LRU Prepare cache */
+public interface PrepareCache {
+
+  /**
+   * Get cache value for key
+   *
+   * @param key key
+   * @param preparedStatement prepared statement
+   * @return Prepare value
+   */
+  Prepare get(String key, ServerPreparedStatement preparedStatement);
+
+  /**
+   * Add a prepare cache value
+   *
+   * @param key key
+   * @param result value
+   * @param preparedStatement prepared statement
+   * @return Prepare if was already cached
+   */
+  Prepare put(String key, Prepare result, ServerPreparedStatement preparedStatement);
+
+  /** Reset cache */
+  void reset();
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/ReadableByteBuf.java b/src/main/java/org/mariadb/jdbc/client/ReadableByteBuf.java
new file mode 100644
index 0000000..06c61a2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/ReadableByteBuf.java
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client;
+
+import org.mariadb.jdbc.MariaDbBlob;
+
+/** Packet buffer interface */
+public interface ReadableByteBuf {
+
+  /**
+   * buffer number of unread bytes
+   *
+   * @return remaining bytes number
+   */
+  int readableBytes();
+
+  /**
+   * Current buffer position
+   *
+   * @return position
+   */
+  int pos();
+
+  /**
+   * buffer
+   *
+   * @return buffer
+   */
+  byte[] buf();
+
+  /**
+   * Reset buffer
+   *
+   * @param buf new buffer
+   * @param limit buffer limit
+   * @param pos initial position
+   */
+  void buf(byte[] buf, int limit, int pos);
+
+  /**
+   * Set position
+   *
+   * @param pos new position
+   */
+  void pos(int pos);
+
+  /** Skip one byte */
+  void skip();
+
+  /**
+   * Skip length value of bytes
+   *
+   * @param length number of position to skip
+   */
+  void skip(int length);
+
+  /** Skip length encoded value */
+  void skipLengthEncoded();
+
+  /**
+   * Read Blob at current position
+   *
+   * @param length blob length
+   * @return Blob
+   */
+  MariaDbBlob readBlob(int length);
+
+  /**
+   * Read byte from buffer at current position, without changing position
+   *
+   * @return byte value
+   */
+  byte getByte();
+
+  /**
+   * Read byte from buffer at indicated index, without changing position
+   *
+   * @param index index
+   * @return byte value
+   */
+  byte getByte(int index);
+
+  /**
+   * Read unsigned byte value at current position, without changing position
+   *
+   * @return short value
+   */
+  short getUnsignedByte();
+
+  /**
+   * Read encoded length value that cannot be null see
+   * https://mariadb.com/kb/en/protocol-data-types/#length-encoded-integers
+   *
+   * @return encoded length
+   */
+  long readLongLengthEncodedNotNull();
+
+  /**
+   * Read encoded length value that cannot be null see
+   * https://mariadb.com/kb/en/protocol-data-types/#length-encoded-integers
+   *
+   * <p>this is readLongLengthEncodedNotNull limited to 32 bits
+   *
+   * @return encoded length
+   */
+  int readIntLengthEncodedNotNull();
+
+  /**
+   * Utility to skip length encoded string, returning initial position
+   *
+   * @return initial position
+   */
+  int skipIdentifier();
+
+  /**
+   * Fast signed long parsing
+   *
+   * @param length data length
+   * @return long value
+   */
+  long atoll(int length);
+
+  /**
+   * Fast unsigned long parsing
+   *
+   * @param length data length
+   * @return long value
+   */
+  long atoull(int length);
+  /**
+   * Read encoded length value see
+   * https://mariadb.com/kb/en/protocol-data-types/#length-encoded-integers
+   *
+   * @return encoded length
+   */
+  Integer readLength();
+
+  /**
+   * Read byte at current position, incrementing position
+   *
+   * @return byte at current position
+   */
+  byte readByte();
+
+  /**
+   * Read unsigned byte value at current position
+   *
+   * @return short value
+   */
+  short readUnsignedByte();
+
+  /**
+   * Read signed 2 bytes value (little endian) at current position
+   *
+   * @return short value
+   */
+  short readShort();
+
+  /**
+   * Read unsigned 2 bytes value (little endian) at current position
+   *
+   * @return short value
+   */
+  int readUnsignedShort();
+
+  /**
+   * Read signed 3 bytes value (little endian) at current position
+   *
+   * @return int value
+   */
+  int readMedium();
+
+  /**
+   * Read unsigned 3 bytes value (little endian) at current position
+   *
+   * @return int value
+   */
+  int readUnsignedMedium();
+
+  /**
+   * Read signed 4 bytes value (little endian) at current position
+   *
+   * @return int value
+   */
+  int readInt();
+
+  /**
+   * Read signed 4 bytes value (big endian) at current position
+   *
+   * @return int value
+   */
+  int readIntBE();
+
+  /**
+   * Read unsigned 4 bytes value (little endian) at current position
+   *
+   * @return long value
+   */
+  long readUnsignedInt();
+
+  /**
+   * Read signed 8 bytes value (little endian) at current position
+   *
+   * @return long value
+   */
+  long readLong();
+
+  /**
+   * Read unsigned 4 bytes value (big endian) at current position
+   *
+   * @return long value
+   */
+  long readLongBE();
+
+  /**
+   * Read as many bytes to fill destination array
+   *
+   * @param dst destination array
+   */
+  void readBytes(byte[] dst);
+
+  /**
+   * Read null-ended encoded bytes. 0x00 null value won't be in return byte, so position is
+   * incremented to returned byte array length + 1
+   *
+   * @return byte array
+   */
+  byte[] readBytesNullEnd();
+
+  /**
+   * Return a length encoded buffer
+   *
+   * @return new buffer
+   */
+  ReadableByteBuf readLengthBuffer();
+
+  /**
+   * Read utf-8 encoded string from length bytes
+   *
+   * @param length length byte to read
+   * @return string value
+   */
+  String readString(int length);
+
+  /**
+   * Read ascii encoded string from length bytes
+   *
+   * @param length length byte to read
+   * @return string value
+   */
+  String readAscii(int length);
+
+  /**
+   * Read null-ended utf-8 encoded string. 0x00 = null represent string ending. Position is
+   * incremented to returned string corresponding bytes + 1
+   *
+   * @return corresponding string
+   */
+  String readStringNullEnd();
+
+  /**
+   * Return the utf-8 string represented by current position to the limit of buffer
+   *
+   * @return string value
+   */
+  String readStringEof();
+
+  /**
+   * Read float encoded on 4 bytes value at current position
+   *
+   * @return float value
+   */
+  float readFloat();
+
+  /**
+   * Read double encoded on 8 bytes value at current position
+   *
+   * @return double value
+   */
+  double readDouble();
+
+  /**
+   * Read double encoded on 8 bytes (big endian) value at current position
+   *
+   * @return double value
+   */
+  double readDoubleBE();
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/ServerVersion.java b/src/main/java/org/mariadb/jdbc/client/ServerVersion.java
new file mode 100644
index 0000000..0ef8177
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/ServerVersion.java
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client;
+
+public interface ServerVersion {
+  /**
+   * Get server version string
+   *
+   * @return server version string
+   */
+  String getVersion();
+
+  /**
+   * get server major version, parsed from server version string
+   *
+   * @return server major version
+   */
+  int getMajorVersion();
+
+  /**
+   * get server minor version, parsed from server version string
+   *
+   * @return server minor version
+   */
+  int getMinorVersion();
+
+  /**
+   * get server patch version, parsed from server version string
+   *
+   * @return server patch version
+   */
+  int getPatchVersion();
+
+  /**
+   * get server qualifier, parsed from server version string
+   *
+   * @return server qualifier
+   */
+  String getQualifier();
+
+  /**
+   * Utility method to check if database version is greater than parameters.
+   *
+   * @param major major version
+   * @param minor minor version
+   * @param patch patch version
+   * @return true if version is greater than parameters
+   */
+  boolean versionGreaterOrEqual(int major, int minor, int patch);
+
+  /**
+   * Is server mariadb
+   *
+   * @return true if server is a MariaDB server
+   */
+  boolean isMariaDBServer();
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/SocketHelper.java b/src/main/java/org/mariadb/jdbc/client/SocketHelper.java
new file mode 100644
index 0000000..c8916c8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/SocketHelper.java
@@ -0,0 +1,35 @@
+package org.mariadb.jdbc.client;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import org.mariadb.jdbc.Configuration;
+
+public class SocketHelper {
+
+  /**
+   * Set socket option
+   *
+   * @param conf configuration
+   * @param socket socket
+   * @throws IOException if any socket error occurs
+   */
+  public static void setSocketOption(final Configuration conf, final Socket socket)
+      throws IOException {
+    socket.setTcpNoDelay(true);
+    socket.setSoTimeout(conf.socketTimeout());
+    if (conf.tcpKeepAlive()) {
+      socket.setKeepAlive(true);
+    }
+    if (conf.tcpAbortiveClose()) {
+      socket.setSoLinger(true, 0);
+    }
+
+    // Bind the socket to a particular interface if the connection property
+    // localSocketAddress has been defined.
+    if (conf.localSocketAddress() != null) {
+      InetSocketAddress localAddress = new InetSocketAddress(conf.localSocketAddress(), 0);
+      socket.bind(localAddress);
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/BigDecimalColumn.java b/src/main/java/org/mariadb/jdbc/client/column/BigDecimalColumn.java
new file mode 100644
index 0000000..527d45b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/BigDecimalColumn.java
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class BigDecimalColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * Constructor for column corresponding to DECIMAL datatype. Class permit specific decoding for
+   * this datatype
+   *
+   * @param buf Column definition MySQL packet buffer
+   * @param charset charset
+   * @param length datatype length
+   * @param dataType data type
+   * @param decimals number of decimals
+   * @param flags column flags
+   * @param stringPos string value position
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public BigDecimalColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return BigDecimal.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.DECIMAL;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "DECIMAL";
+  }
+
+  public int getPrecision() {
+    // DECIMAL and OLDDECIMAL are  "exact" fixed-point number.
+    // so :
+    // - if is signed, 1 byte is saved for sign
+    // - if decimal > 0, one byte more for dot
+    if (isSigned()) {
+      return (int) (columnLength - ((decimals > 0) ? 2 : 1));
+    } else {
+      return (int) (columnLength - ((decimals > 0) ? 1 : 0));
+    }
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return new BigDecimal(buf.readAscii(length));
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return new BigDecimal(buf.readAscii(length));
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return new BigDecimal(buf.readAscii(length)).intValue() != 0;
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeBooleanText(buf, length);
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str = buf.readString(length);
+    try {
+      return new BigDecimal(str).setScale(0, RoundingMode.DOWN).byteValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Byte", str, dataType));
+    }
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeByteText(buf, length);
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Short", str));
+    }
+    if ((short) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeShortText(buf, length);
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Integer", str));
+    }
+    int res = (int) result;
+    if (res != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeIntText(buf, length);
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str2 = buf.readAscii(length);
+    try {
+      return new BigDecimal(str2).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Long", str2));
+    }
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str = buf.readString(length);
+    try {
+      return new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Long", str));
+    }
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return new BigDecimal(buf.readAscii(length)).floatValue();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return new BigDecimal(buf.readAscii(length)).doubleValue();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/BitColumn.java b/src/main/java/org/mariadb/jdbc/client/column/BitColumn.java
new file mode 100644
index 0000000..fbf752d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/BitColumn.java
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+import org.mariadb.jdbc.plugin.codec.ByteCodec;
+
+/** Column metadata definition */
+public class BitColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+  /**
+   * Constructor for column corresponding to BIT datatype. Class permit specific decoding for this
+   * datatype
+   *
+   * @param buf Column definition MySQL packet buffer
+   * @param charset charset
+   * @param length datatype length
+   * @param dataType data type
+   * @param decimals number of decimals
+   * @param flags column flags
+   * @param stringPos string value position
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public BitColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return columnLength == 1 ? Boolean.class.getName() : "byte[]";
+  }
+
+  public int getColumnType(Configuration conf) {
+    return columnLength == 1 ? Types.BOOLEAN : Types.VARBINARY;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "BIT";
+  }
+
+  public int getPrecision() {
+    return (int) columnLength;
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (columnLength == 1) {
+      return ByteCodec.parseBit(buf, length) != 0;
+    }
+    byte[] arr = new byte[length];
+    buf.readBytes(arr);
+    return arr;
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return getDefaultText(conf, buf, length);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return ByteCodec.parseBit(buf, length) != 0;
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return ByteCodec.parseBit(buf, length) != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    byte val = buf.readByte();
+    if (length > 1) buf.skip(length - 1);
+    return val;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeByteText(buf, length);
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    byte[] bytes = new byte[length];
+    buf.readBytes(bytes);
+    StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE + 3);
+    sb.append("b'");
+    boolean firstByteNonZero = false;
+    for (int i = 0; i < Byte.SIZE * bytes.length; i++) {
+      boolean b = (bytes[i / Byte.SIZE] & 1 << (Byte.SIZE - 1 - (i % Byte.SIZE))) > 0;
+      if (b) {
+        sb.append('1');
+        firstByteNonZero = true;
+      } else if (firstByteNonZero) {
+        sb.append('0');
+      }
+    }
+    sb.append("'");
+    return sb.toString();
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    byte[] bytes = new byte[length];
+    buf.readBytes(bytes);
+    StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE + 3);
+    sb.append("b'");
+    boolean firstByteNonZero = false;
+    for (int i = 0; i < Byte.SIZE * bytes.length; i++) {
+      boolean b = (bytes[i / Byte.SIZE] & 1 << (Byte.SIZE - 1 - (i % Byte.SIZE))) > 0;
+      if (b) {
+        sb.append('1');
+        firstByteNonZero = true;
+      } else if (firstByteNonZero) {
+        sb.append('0');
+      }
+    }
+    sb.append("'");
+    return sb.toString();
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = 0;
+    for (int i = 0; i < length; i++) {
+      byte b = buf.readByte();
+      result = (result << 8) + (b & 0xff);
+    }
+    if ((short) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeShortText(buf, length);
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = 0;
+    for (int i = 0; i < length; i++) {
+      byte b = buf.readByte();
+      result = (result << 8) + (b & 0xff);
+    }
+    int res = (int) result;
+    if (res != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = 0;
+    for (int i = 0; i < length; i++) {
+      byte b = buf.readByte();
+      result = (result << 8) + (b & 0xff);
+    }
+
+    int res = (int) result;
+    if (res != result) {
+      throw new SQLDataException("integer overflow");
+    }
+
+    return res;
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = 0;
+    for (int i = 0; i < length; i++) {
+      byte b = buf.readByte();
+      result = (result << 8) + (b & 0xff);
+    }
+    return result;
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeLongText(buf, length);
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/BlobColumn.java b/src/main/java/org/mariadb/jdbc/client/column/BlobColumn.java
new file mode 100644
index 0000000..a23c873
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/BlobColumn.java
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.Locale;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.util.CharsetEncodingLength;
+
+/** Column metadata definition */
+public class BlobColumn extends StringColumn implements ColumnDecoder {
+  /**
+   * Constructor for column corresponding to BLOB datatype. Class permit specific decoding for this
+   * datatype
+   *
+   * @param buf Column definition MySQL packet buffer
+   * @param charset charset
+   * @param length datatype length
+   * @param dataType data type
+   * @param decimals number of decimals
+   * @param flags column flags
+   * @param stringPos string value position
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public BlobColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return isBinary() ? Blob.class.getName() : String.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    if (columnLength <= 0 || getDisplaySize() > 16777215) {
+      return isBinary() ? Types.LONGVARBINARY : Types.LONGVARCHAR;
+    } else {
+      if (dataType == DataType.TINYBLOB || dataType == DataType.BLOB) {
+        return isBinary() ? Types.VARBINARY : Types.VARCHAR;
+      }
+      return isBinary() ? Types.LONGVARBINARY : Types.LONGVARCHAR;
+    }
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    /*
+     map to different blob types based on datatype length
+     see https://mariadb.com/kb/en/library/data-types/
+    */
+    if (extTypeFormat != null) {
+      return extTypeFormat.toUpperCase(Locale.ROOT);
+    }
+    if (isBinary()) {
+      if (columnLength < 0) {
+        return "LONGBLOB";
+      } else if (columnLength <= 255) {
+        return "TINYBLOB";
+      } else if (columnLength <= 65535) {
+        return "BLOB";
+      } else if (columnLength <= 16777215) {
+        return "MEDIUMBLOB";
+      } else {
+        return "LONGBLOB";
+      }
+    } else {
+      if (columnLength < 0) {
+        return "LONGTEXT";
+      } else if (getDisplaySize() <= 65532) {
+        return "VARCHAR";
+      } else if (getDisplaySize() <= 65535) {
+        return "TEXT";
+      } else if (getDisplaySize() <= 16777215) {
+        return "MEDIUMTEXT";
+      } else {
+        return "LONGTEXT";
+      }
+    }
+  }
+
+  public int getPrecision() {
+    if (!isBinary()) {
+      Integer maxWidth2 = CharsetEncodingLength.maxCharlen.get(charset);
+      if (maxWidth2 != null) return (int) (columnLength / maxWidth2);
+    }
+    return (int) columnLength;
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (isBinary()) {
+      return buf.readBlob(length);
+    }
+    return buf.readString(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return getDefaultText(conf, buf, length);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Boolean", dataType));
+    }
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeBooleanText(buf, length);
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    if (!isBinary()) {
+      // TEXT column
+      String str2 = buf.readString(length);
+      try {
+        result = new BigDecimal(str2).setScale(0, RoundingMode.DOWN).longValue();
+      } catch (NumberFormatException nfe) {
+        throw new SQLDataException(
+            String.format("value '%s' (%s) cannot be decoded as Byte", str2, dataType));
+      }
+      if ((byte) result != result) {
+        throw new SQLDataException("byte overflow");
+      }
+
+      return (byte) result;
+    }
+    if (length > 0) {
+      byte b = buf.readByte();
+      buf.skip(length - 1);
+      return b;
+    }
+    throw new SQLDataException("empty String value cannot be decoded as Byte");
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeByteText(buf, length);
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Short", dataType));
+    }
+    return super.decodeShortText(buf, length);
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Short", dataType));
+    }
+    return super.decodeShortBinary(buf, length);
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Integer", dataType));
+    }
+    return super.decodeIntText(buf, length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Integer", dataType));
+    }
+    return super.decodeIntBinary(buf, length);
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+    }
+    return super.decodeLongText(buf, length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+    }
+    return super.decodeLongBinary(buf, length);
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Float", dataType));
+    }
+    return super.decodeFloatText(buf, length);
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Float", dataType));
+    }
+    return super.decodeFloatText(buf, length);
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Double", dataType));
+    }
+    return super.decodeDoubleText(buf, length);
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Double", dataType));
+    }
+    return super.decodeDoubleBinary(buf, length);
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+    }
+    return super.decodeDateText(buf, length, cal);
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+    }
+    return super.decodeDateBinary(buf, length, cal);
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+    }
+    return super.decodeTimeText(buf, length, cal);
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+    }
+    return super.decodeTimeBinary(buf, length, cal);
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Timestamp", dataType));
+    }
+    return super.decodeTimestampText(buf, length, cal);
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (isBinary()) {
+      buf.skip(length);
+      throw new SQLDataException(
+          String.format("Data type %s cannot be decoded as Timestamp", dataType));
+    }
+    return super.decodeTimestampBinary(buf, length, cal);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/DateColumn.java b/src/main/java/org/mariadb/jdbc/client/column/DateColumn.java
new file mode 100644
index 0000000..28a0009
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/DateColumn.java
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.time.LocalDate;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class DateColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * Date metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public DateColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Date.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.DATE;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "DATE";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeDateText(buf, length, null);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeDateBinary(buf, length, null);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Boolean", dataType));
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Boolean", dataType));
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Byte", dataType));
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Byte", dataType));
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (length == 0) return "0000-00-00";
+    int dateYear = buf.readUnsignedShort();
+    int dateMonth = buf.readByte();
+    int dateDay = buf.readByte();
+    return LocalDate.of(dateYear, dateMonth, dateDay).toString();
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Short", dataType));
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Short", dataType));
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Integer", dataType));
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Integer", dataType));
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    int year = (int) buf.atoull(4);
+    buf.skip(1);
+    int month = (int) buf.atoull(2);
+    buf.skip(1);
+    int dayOfMonth = (int) buf.atoull(2);
+    if (year == 0 && month == 0 && dayOfMonth == 0) return null;
+
+    Calendar c = cal == null ? Calendar.getInstance() : cal;
+    synchronized (c) {
+      c.clear();
+      c.set(Calendar.YEAR, year);
+      c.set(Calendar.MONTH, month - 1);
+      c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+      return new Date(c.getTimeInMillis());
+    }
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (length == 0) return null;
+
+    Calendar c = cal == null ? Calendar.getInstance() : cal;
+    synchronized (c) {
+      c.clear();
+      c.set(Calendar.YEAR, buf.readShort());
+      c.set(Calendar.MONTH, buf.readByte() - 1);
+      c.set(Calendar.DAY_OF_MONTH, buf.readByte());
+      return new Date(c.getTimeInMillis());
+    }
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    if (calParam == null || calParam.getTimeZone().equals(TimeZone.getDefault())) {
+      String s = buf.readAscii(length);
+      if ("0000-00-00".equals(s)) return null;
+      return new Timestamp(Date.valueOf(s).getTime());
+    }
+
+    String[] datePart = buf.readAscii(length).split("-");
+    synchronized (calParam) {
+      calParam.clear();
+      calParam.set(
+          Integer.parseInt(datePart[0]),
+          Integer.parseInt(datePart[1]) - 1,
+          Integer.parseInt(datePart[2]));
+      return new Timestamp(calParam.getTimeInMillis());
+    }
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    if (length == 0) return null;
+
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    int year;
+    int month;
+    long dayOfMonth;
+
+    year = buf.readUnsignedShort();
+    month = buf.readByte();
+    dayOfMonth = buf.readByte();
+
+    if (year == 0 && month == 0 && dayOfMonth == 0) return null;
+
+    Timestamp timestamp;
+    synchronized (cal) {
+      cal.clear();
+      cal.set(year, month - 1, (int) dayOfMonth, 0, 0, 0);
+      timestamp = new Timestamp(cal.getTimeInMillis());
+    }
+    timestamp.setNanos(0);
+    return timestamp;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/DoubleColumn.java b/src/main/java/org/mariadb/jdbc/client/column/DoubleColumn.java
new file mode 100644
index 0000000..c8571df
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/DoubleColumn.java
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class DoubleColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * Double metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public DoubleColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Double.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.DOUBLE;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "DOUBLE";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.readDouble();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return ((int) buf.readDouble()) != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).byteValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Byte", str, dataType));
+    }
+    if ((byte) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = (long) buf.readDouble();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return String.valueOf(buf.readDouble());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Short", str));
+    }
+    if ((short) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("Short overflow");
+    }
+
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = (long) buf.readDouble();
+    if ((short) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Integer", str));
+    }
+
+    int res = (int) result;
+    if (res != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = (long) buf.readDouble();
+    int res = (int) result;
+    if (res != result) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str2 = buf.readAscii(length);
+    try {
+      return new BigDecimal(str2).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Long", str2));
+    }
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (long) buf.readDouble();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (float) buf.readDouble();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readDouble();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/FloatColumn.java b/src/main/java/org/mariadb/jdbc/client/column/FloatColumn.java
new file mode 100644
index 0000000..365ecaf
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/FloatColumn.java
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class FloatColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * Float metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public FloatColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Float.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.REAL;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "FLOAT";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.readFloat();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return ((int) buf.readFloat()) != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).byteValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Byte", str, dataType));
+    }
+    if ((byte) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = (long) buf.readFloat();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return String.valueOf(buf.readFloat());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Short", str));
+    }
+    if ((short) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("Short overflow");
+    }
+
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = (long) buf.readFloat();
+    if ((short) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result;
+    String str = buf.readString(length);
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Integer", str));
+    }
+
+    int res = (int) result;
+    if (res != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = (long) buf.readFloat();
+    int res = (int) result;
+    if (res != result) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str2 = buf.readAscii(length);
+    try {
+      return new BigDecimal(str2).setScale(0, RoundingMode.DOWN).longValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Long", str2));
+    }
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (long) buf.readFloat();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readFloat();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readFloat();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/GeometryColumn.java b/src/main/java/org/mariadb/jdbc/client/column/GeometryColumn.java
new file mode 100644
index 0000000..37bd06f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/GeometryColumn.java
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import java.util.Locale;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.plugin.codec.*;
+import org.mariadb.jdbc.type.*;
+
+/** Column metadata definition */
+public class GeometryColumn extends BlobColumn {
+
+  /**
+   * Geometry metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public GeometryColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    if (conf.geometryDefaultType() != null && "default".equals(conf.geometryDefaultType())) {
+      if (extTypeName != null) {
+        switch (extTypeName) {
+          case "point":
+            return Point.class.getName();
+          case "linestring":
+            return LineString.class.getName();
+          case "polygon":
+            return Polygon.class.getName();
+          case "multipoint":
+            return MultiPoint.class.getName();
+          case "multilinestring":
+            return MultiLineString.class.getName();
+          case "multipolygon":
+            return MultiPolygon.class.getName();
+          case "geometrycollection":
+            return GeometryCollection.class.getName();
+        }
+      }
+      return GeometryCollection.class.getName();
+    }
+    return "byte[]";
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.VARBINARY;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    if (extTypeName != null) {
+      return extTypeName.toUpperCase(Locale.ROOT);
+    }
+    return "GEOMETRY";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (conf.geometryDefaultType() != null && "default".equals(conf.geometryDefaultType())) {
+      buf.skip(4); // SRID
+      return Geometry.getGeometry(buf, length - 4, this);
+    }
+    byte[] arr = new byte[length];
+    buf.readBytes(arr);
+    return arr;
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return getDefaultText(conf, buf, length);
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/JsonColumn.java b/src/main/java/org/mariadb/jdbc/client/column/JsonColumn.java
new file mode 100644
index 0000000..a3fb29c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/JsonColumn.java
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+
+/** Column metadata definition */
+public class JsonColumn extends StringColumn implements ColumnDecoder {
+
+  /**
+   * JSON metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public JsonColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return String.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.LONGVARCHAR;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "JSON";
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/SignedBigIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/SignedBigIntColumn.java
new file mode 100644
index 0000000..5afd95b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/SignedBigIntColumn.java
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.math.BigInteger;
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class SignedBigIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * BIGINT metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public SignedBigIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Long.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.BIGINT;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "BIGINT";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.atoll(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.readLong();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readLong() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readLong();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return BigInteger.valueOf(buf.readLong()).toString();
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readLong();
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    int res = (int) result;
+    if (res != result) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readLong();
+    int res = (int) result;
+    if (res != result) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoll(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readLong();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (float) buf.readLong();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readLong();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/SignedIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/SignedIntColumn.java
new file mode 100644
index 0000000..5cebf4b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/SignedIntColumn.java
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class SignedIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * INTEGER metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public SignedIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Integer.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.INTEGER;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "INTEGER";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return (int) buf.atoll(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.readInt();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readInt() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((byte) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readInt();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return String.valueOf(buf.readInt());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = isSigned() ? buf.readInt() : buf.readUnsignedInt();
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (int) buf.atoll(length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readInt();
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoll(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readInt();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (float) buf.readInt();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readInt();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/SignedMediumIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/SignedMediumIntColumn.java
new file mode 100644
index 0000000..2f03e1f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/SignedMediumIntColumn.java
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class SignedMediumIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * MEDIUM INTEGER metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public SignedMediumIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Integer.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.INTEGER;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "MEDIUMINT";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeIntText(buf, length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeIntBinary(buf, length);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readInt() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    String mediumStr = String.valueOf(isSigned() ? buf.readMedium() : buf.readUnsignedMedium());
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return mediumStr;
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (int) buf.atoll(length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    int res = buf.readMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return res;
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoll(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long l = buf.readMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return l;
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    float f = buf.readMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return f;
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    double f = buf.readMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return f;
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/SignedSmallIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/SignedSmallIntColumn.java
new file mode 100644
index 0000000..232591d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/SignedSmallIntColumn.java
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class SignedSmallIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * SMALLINT metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public SignedSmallIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Short.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.SMALLINT;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return isSigned() ? "SMALLINT" : "SMALLINT UNSIGNED";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return (short) buf.atoll(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.readShort();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readShort() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readShort();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return String.valueOf(buf.readShort());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (short) buf.atoll(length);
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readShort();
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (int) buf.atoll(length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readShort();
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoll(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readShort();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readShort();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readShort();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/SignedTinyIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/SignedTinyIntColumn.java
new file mode 100644
index 0000000..2f79f8c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/SignedTinyIntColumn.java
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class SignedTinyIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * TINYINT metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public SignedTinyIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    if (conf.tinyInt1isBit() && columnLength == 1) return Boolean.class.getName();
+    return Integer.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return conf.transformedBitIsBoolean() ? Types.BOOLEAN : Types.BIT;
+    }
+    return isSigned() ? Types.TINYINT : Types.SMALLINT;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return conf.transformedBitIsBoolean() ? "BOOLEAN" : "BIT";
+    }
+    return isSigned() ? "TINYINT" : "TINYINT UNSIGNED";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return decodeBooleanText(buf, length);
+    }
+    return (int) buf.atoll(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return decodeBooleanBinary(buf, length);
+    }
+    if (isSigned()) {
+      return (int) buf.readByte();
+    }
+    return (int) buf.readUnsignedByte();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readByte() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (isSigned()) return buf.readByte();
+    long result = buf.readUnsignedByte();
+
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (!isSigned()) {
+      return String.valueOf(buf.readUnsignedByte());
+    }
+    return String.valueOf(buf.readByte());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (short) buf.atoll(length);
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (isSigned() ? buf.readByte() : buf.readUnsignedByte());
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (int) buf.atoll(length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (isSigned() ? buf.readByte() : buf.readUnsignedByte());
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoll(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (!isSigned()) {
+      return buf.readUnsignedByte();
+    }
+    return buf.readByte();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (!isSigned()) {
+      return buf.readUnsignedByte();
+    }
+    return buf.readByte();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (!isSigned()) {
+      return buf.readUnsignedByte();
+    }
+    return buf.readByte();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/StringColumn.java b/src/main/java/org/mariadb/jdbc/client/column/StringColumn.java
new file mode 100644
index 0000000..7338478
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/StringColumn.java
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.sql.*;
+import java.time.DateTimeException;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+import org.mariadb.jdbc.plugin.codec.LocalDateTimeCodec;
+import org.mariadb.jdbc.plugin.codec.LocalTimeCodec;
+import org.mariadb.jdbc.util.CharsetEncodingLength;
+
+/** Column metadata definition */
+public class StringColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * VARCHAR/STRING/VARSTRING metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public StringColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return isBinary() ? "byte[]" : String.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    if (dataType == DataType.NULL) {
+      return Types.NULL;
+    }
+    if (dataType == DataType.STRING) {
+      return isBinary() ? Types.VARBINARY : Types.CHAR;
+    }
+    if (columnLength <= 0 || getDisplaySize() > 16777215) {
+      return isBinary() ? Types.LONGVARBINARY : Types.LONGVARCHAR;
+    }
+    return isBinary() ? Types.VARBINARY : Types.VARCHAR;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    switch (dataType) {
+      case STRING:
+        if (isBinary()) {
+          return "BINARY";
+        }
+        return "CHAR";
+      case VARSTRING:
+      case VARCHAR:
+        if (isBinary()) {
+          return "VARBINARY";
+        }
+        if (columnLength < 0) {
+          return "LONGTEXT";
+        } else if (getDisplaySize() <= 65532) {
+          return "VARCHAR";
+        } else if (getDisplaySize() <= 65535) {
+          return "TEXT";
+        } else if (getDisplaySize() <= 16777215) {
+          return "MEDIUMTEXT";
+        } else {
+          return "LONGTEXT";
+        }
+      default:
+        return dataType.name();
+    }
+  }
+
+  public int getPrecision() {
+    Integer maxWidth = CharsetEncodingLength.maxCharlen.get(charset);
+    if (maxWidth == null) {
+      return (int) columnLength;
+    }
+    return (int) (columnLength / maxWidth);
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (isBinary()) {
+      byte[] arr = new byte[length];
+      buf.readBytes(arr);
+      return arr;
+    }
+    return buf.readString(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (isBinary()) {
+      byte[] arr = new byte[length];
+      buf.readBytes(arr);
+      return arr;
+    }
+    return buf.readString(length);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return !"0".equals(buf.readAscii(length));
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return !"0".equals(buf.readAscii(length));
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str = buf.readString(length);
+    long result;
+    try {
+      result = new BigDecimal(str).setScale(0, RoundingMode.DOWN).longValue();
+    } catch (NumberFormatException nfe) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Byte", str, dataType));
+    }
+    if ((byte) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeByteText(buf, length);
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str = buf.readString(length);
+    try {
+      return new BigDecimal(str).setScale(0, RoundingMode.DOWN).shortValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Short", str));
+    }
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeShortText(buf, length);
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str = buf.readString(length);
+    try {
+      return new BigDecimal(str).setScale(0, RoundingMode.DOWN).intValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Integer", str));
+    }
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeIntText(buf, length);
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str = buf.readString(length);
+    try {
+      return new BigInteger(str).longValueExact();
+    } catch (NumberFormatException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Long", str));
+    }
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeLongText(buf, length);
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String val = buf.readString(length);
+    try {
+      return Float.parseFloat(val);
+    } catch (NumberFormatException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Float", val));
+    }
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeFloatText(buf, length);
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String str2 = buf.readString(length);
+    try {
+      return Double.parseDouble(str2);
+    } catch (NumberFormatException nfe) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Double", str2));
+    }
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return decodeDoubleText(buf, length);
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    String val = buf.readString(length);
+    if ("0000-00-00".equals(val)) return null;
+    String[] stDatePart = val.split("[- ]");
+    if (stDatePart.length < 3) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Date", val, dataType));
+    }
+
+    try {
+      int year = Integer.parseInt(stDatePart[0]);
+      int month = Integer.parseInt(stDatePart[1]);
+      int dayOfMonth = Integer.parseInt(stDatePart[2]);
+      Calendar c = cal == null ? Calendar.getInstance() : cal;
+      synchronized (c) {
+        c.clear();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month - 1);
+        c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+        return new Date(c.getTimeInMillis());
+      }
+
+    } catch (NumberFormatException nfe) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Date", val, dataType));
+    }
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return decodeDateText(buf, length, cal);
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    Calendar c = cal == null ? Calendar.getInstance() : cal;
+    int offset = c.getTimeZone().getOffset(0);
+    int[] parts = LocalTimeCodec.parseTime(buf, length, this);
+    long timeInMillis =
+        (parts[1] * 3_600_000L + parts[2] * 60_000L + parts[3] * 1_000L + parts[4] / 1_000_000)
+                * parts[0]
+            - offset;
+    return new Time(timeInMillis);
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    int[] parts = LocalTimeCodec.parseTime(buf, length, this);
+    Time t;
+
+    // specific case for TIME, to handle value not in 00:00:00-23:59:59
+    synchronized (cal) {
+      cal.clear();
+      cal.setLenient(true);
+      if (parts[0] == -1) {
+        cal.set(
+            1970,
+            Calendar.JANUARY,
+            1,
+            parts[0] * parts[1],
+            parts[0] * parts[2],
+            parts[0] * parts[3] - 1);
+        t = new Time(cal.getTimeInMillis() + (1000 - parts[4]));
+      } else {
+        cal.set(1970, Calendar.JANUARY, 1, parts[1], parts[2], parts[3]);
+        t = new Time(cal.getTimeInMillis() + parts[4] / 1_000_000);
+      }
+    }
+    return t;
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    int pos = buf.pos();
+    int nanoBegin = -1;
+    int[] timestampsPart = new int[] {0, 0, 0, 0, 0, 0, 0};
+    int partIdx = 0;
+    for (int begin = 0; begin < length; begin++) {
+      byte b = buf.readByte();
+      if (b == '-' || b == ' ' || b == ':') {
+        partIdx++;
+        continue;
+      }
+      if (b == '.') {
+        partIdx++;
+        nanoBegin = begin;
+        continue;
+      }
+      if (b < '0' || b > '9') {
+        buf.pos(pos);
+        throw new SQLDataException(
+            String.format(
+                "value '%s' (%s) cannot be decoded as Timestamp",
+                buf.readString(length), dataType));
+      }
+
+      timestampsPart[partIdx] = timestampsPart[partIdx] * 10 + b - 48;
+    }
+    if (timestampsPart[0] == 0
+        && timestampsPart[1] == 0
+        && timestampsPart[2] == 0
+        && timestampsPart[3] == 0
+        && timestampsPart[4] == 0
+        && timestampsPart[5] == 0
+        && timestampsPart[6] == 0) {
+      return null;
+    }
+
+    // fix non-leading tray for nanoseconds
+    if (nanoBegin > 0) {
+      for (int begin = 0; begin < 6 - (length - nanoBegin - 1); begin++) {
+        timestampsPart[6] = timestampsPart[6] * 10;
+      }
+    }
+
+    Timestamp timestamp;
+    if (calParam == null) {
+      Calendar c = Calendar.getInstance();
+      c.set(
+          timestampsPart[0],
+          timestampsPart[1] - 1,
+          timestampsPart[2],
+          timestampsPart[3],
+          timestampsPart[4],
+          timestampsPart[5]);
+      timestamp = new Timestamp(c.getTime().getTime());
+      timestamp.setNanos(timestampsPart[6] * 1000);
+    } else {
+      synchronized (calParam) {
+        calParam.clear();
+        calParam.set(
+            timestampsPart[0],
+            timestampsPart[1] - 1,
+            timestampsPart[2],
+            timestampsPart[3],
+            timestampsPart[4],
+            timestampsPart[5]);
+        timestamp = new Timestamp(calParam.getTime().getTime());
+        timestamp.setNanos(timestampsPart[6] * 1000);
+      }
+    }
+    return timestamp;
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+
+    String val = buf.readString(length);
+    try {
+      int[] parts = LocalDateTimeCodec.parseTimestamp(val);
+      if (parts == null) return null;
+      int year = parts[0];
+      int month = parts[1];
+      int dayOfMonth = parts[2];
+      int hour = parts[3];
+      int minutes = parts[4];
+      int seconds = parts[5];
+      int microseconds = parts[6] / 1000;
+      Timestamp timestamp;
+      synchronized (cal) {
+        cal.clear();
+        cal.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
+        timestamp = new Timestamp(cal.getTimeInMillis());
+      }
+      timestamp.setNanos(microseconds * 1000);
+      return timestamp;
+
+    } catch (DateTimeException dte) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Timestamp", val, dataType));
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/TimeColumn.java b/src/main/java/org/mariadb/jdbc/client/column/TimeColumn.java
new file mode 100644
index 0000000..5ac66be
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/TimeColumn.java
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+import org.mariadb.jdbc.plugin.codec.LocalTimeCodec;
+
+/** Column metadata definition */
+public class TimeColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * TIME metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public TimeColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Time.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.TIME;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "TIME";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    Calendar c = Calendar.getInstance();
+    int offset = c.getTimeZone().getOffset(0);
+    int[] parts = LocalTimeCodec.parseTime(buf, length, this);
+    long timeInMillis =
+        (parts[1] * 3_600_000L + parts[2] * 60_000L + parts[3] * 1_000L + parts[4] / 1_000_000)
+                * parts[0]
+            - offset;
+    return new Time(timeInMillis);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    boolean negate = false;
+    Calendar cal = Calendar.getInstance();
+    long dayOfMonth = 0;
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+    if (length > 0) {
+      // specific case for TIME, to handle value not in 00:00:00-23:59:59
+      negate = buf.readByte() == 1;
+      dayOfMonth = buf.readUnsignedInt();
+      hour = buf.readByte();
+      minutes = buf.readByte();
+      seconds = buf.readByte();
+      if (length > 8) {
+        microseconds = buf.readUnsignedInt();
+      }
+    }
+    int offset = cal.getTimeZone().getOffset(0);
+    long timeInMillis =
+        ((24 * dayOfMonth + hour) * 3_600_000
+                    + minutes * 60_000
+                    + seconds * 1_000
+                    + microseconds / 1_000)
+                * (negate ? -1 : 1)
+            - offset;
+    return new Time(timeInMillis);
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Byte", dataType));
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Byte", dataType));
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Boolean", dataType));
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Boolean", dataType));
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    long tDays = 0;
+    int tHours = 0;
+    int tMinutes = 0;
+    int tSeconds = 0;
+    long tMicroseconds = 0;
+    if (length == 0) {
+      StringBuilder zeroValue = new StringBuilder("00:00:00");
+      if (getDecimals() > 0) {
+        zeroValue.append(".");
+        for (int i = 0; i < getDecimals(); i++) zeroValue.append("0");
+      }
+      return zeroValue.toString();
+    }
+    boolean negate = buf.readByte() == 0x01;
+    if (length > 4) {
+      tDays = buf.readUnsignedInt();
+      if (length > 7) {
+        tHours = buf.readByte();
+        tMinutes = buf.readByte();
+        tSeconds = buf.readByte();
+        if (length > 8) {
+          tMicroseconds = buf.readInt();
+        }
+      }
+    }
+    int totalHour = (int) (tDays * 24 + tHours);
+    String stTime =
+        (negate ? "-" : "")
+            + (totalHour < 10 ? "0" : "")
+            + totalHour
+            + ":"
+            + (tMinutes < 10 ? "0" : "")
+            + tMinutes
+            + ":"
+            + (tSeconds < 10 ? "0" : "")
+            + tSeconds;
+    if (getDecimals() == 0) {
+      if (tMicroseconds == 0) return stTime;
+      // possible for Xpand that doesn't send some metadata
+      // https://jira.mariadb.org/browse/XPT-273
+      StringBuilder stMicro = new StringBuilder(String.valueOf(tMicroseconds));
+      while (stMicro.length() < 6) {
+        stMicro.insert(0, "0");
+      }
+      return stTime + "." + stMicro;
+    }
+    StringBuilder stMicro = new StringBuilder(String.valueOf(tMicroseconds));
+    while (stMicro.length() < getDecimals()) {
+      stMicro.insert(0, "0");
+    }
+    return stTime + "." + stMicro;
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Short", dataType));
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Short", dataType));
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Integer", dataType));
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Integer", dataType));
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    Calendar c = cal == null ? Calendar.getInstance() : cal;
+    int offset = c.getTimeZone().getOffset(0);
+    int[] parts = LocalTimeCodec.parseTime(buf, length, this);
+    long timeInMillis =
+        (parts[1] * 3_600_000L + parts[2] * 60_000L + parts[3] * 1_000L + parts[4] / 1_000_000)
+                * parts[0]
+            - offset;
+    return new Time(timeInMillis);
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    long dayOfMonth = 0;
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+    boolean negate = false;
+    if (length > 0) {
+      // specific case for TIME, to handle value not in 00:00:00-23:59:59
+      negate = buf.readByte() == 1;
+      dayOfMonth = buf.readUnsignedInt();
+      hour = buf.readByte();
+      minutes = buf.readByte();
+      seconds = buf.readByte();
+      if (length > 8) {
+        microseconds = buf.readUnsignedInt();
+      }
+    }
+    int offset = cal.getTimeZone().getOffset(0);
+    long timeInMillis =
+        ((24 * dayOfMonth + hour) * 3_600_000
+                    + minutes * 60_000
+                    + seconds * 1_000
+                    + microseconds / 1_000)
+                * (negate ? -1 : 1)
+            - offset;
+    return new Time(timeInMillis);
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    int[] parts = LocalTimeCodec.parseTime(buf, length, this);
+    Timestamp t;
+
+    // specific case for TIME, to handle value not in 00:00:00-23:59:59
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    synchronized (cal) {
+      cal.clear();
+      cal.setLenient(true);
+      if (parts[0] == -1) {
+        cal.set(
+            1970,
+            Calendar.JANUARY,
+            1,
+            parts[0] * parts[1],
+            parts[0] * parts[2],
+            parts[0] * parts[3] - 1);
+        t = new Timestamp(cal.getTimeInMillis());
+        t.setNanos(1_000_000_000 - parts[4]);
+      } else {
+        cal.set(1970, Calendar.JANUARY, 1, parts[1], parts[2], parts[3]);
+        t = new Timestamp(cal.getTimeInMillis());
+        t.setNanos(parts[4]);
+      }
+    }
+    return t;
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    long microseconds = 0;
+
+    // specific case for TIME, to handle value not in 00:00:00-23:59:59
+    boolean negate = buf.readByte() == 1;
+    long dayOfMonth = buf.readUnsignedInt();
+    int hour = buf.readByte();
+    int minutes = buf.readByte();
+    int seconds = buf.readByte();
+    if (length > 8) {
+      microseconds = buf.readUnsignedInt();
+    }
+    int offset = cal.getTimeZone().getOffset(0);
+    long timeInMillis =
+        ((24 * dayOfMonth + hour) * 3_600_000
+                    + minutes * 60_000
+                    + seconds * 1_000
+                    + microseconds / 1_000)
+                * (negate ? -1 : 1)
+            - offset;
+    return new Timestamp(timeInMillis);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/TimestampColumn.java b/src/main/java/org/mariadb/jdbc/client/column/TimestampColumn.java
new file mode 100644
index 0000000..fd9d90e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/TimestampColumn.java
@@ -0,0 +1,498 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+import org.mariadb.jdbc.plugin.codec.LocalDateTimeCodec;
+import org.mariadb.jdbc.plugin.codec.TimeCodec;
+
+/** Column metadata definition */
+public class TimestampColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * TIMESTAMP metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public TimestampColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Timestamp.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.TIMESTAMP;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return dataType.name();
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeTimestampText(buf, length, null);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeTimestampBinary(buf, length, null);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Boolean", dataType));
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Boolean", dataType));
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Byte", dataType));
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Byte", dataType));
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    if (length == 0) {
+      StringBuilder zeroValue = new StringBuilder("0000-00-00 00:00:00");
+      if (getDecimals() > 0) {
+        zeroValue.append(".");
+        for (int i = 0; i < getDecimals(); i++) zeroValue.append("0");
+      }
+      return zeroValue.toString();
+    }
+    int year = buf.readUnsignedShort();
+    int month = buf.readByte();
+    int day = buf.readByte();
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+
+    if (length > 4) {
+      hour = buf.readByte();
+      minutes = buf.readByte();
+      seconds = buf.readByte();
+
+      if (length > 7) {
+        microseconds = buf.readUnsignedInt();
+      }
+    }
+
+    // xpand workaround https://jira.mariadb.org/browse/XPT-274
+    if (year == 0 && month == 0 && day == 0) {
+      return "0000-00-00 00:00:00";
+    }
+
+    LocalDateTime dateTime =
+        LocalDateTime.of(year, month, day, hour, minutes, seconds).plusNanos(microseconds * 1000);
+
+    StringBuilder microSecPattern = new StringBuilder();
+    if (getDecimals() > 0 || microseconds > 0) {
+      int decimal = getDecimals() & 0xff;
+      if (decimal == 0) decimal = 6;
+      microSecPattern.append(".");
+      for (int i = 0; i < decimal; i++) microSecPattern.append("S");
+    }
+    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss" + microSecPattern);
+    return dateTime.toLocalDate().toString() + ' ' + dateTime.toLocalTime().format(formatter);
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Short", dataType));
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Short", dataType));
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Integer", dataType));
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Integer", dataType));
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Long", dataType));
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Float", dataType));
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Double", dataType));
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+
+    int pos = buf.pos();
+    int nanoBegin = -1;
+    int[] timestampsPart = new int[] {0, 0, 0, 0, 0, 0, 0};
+    int partIdx = 0;
+    for (int begin = 0; begin < length; begin++) {
+      byte b = buf.readByte();
+      if (b == '-' || b == ' ' || b == ':') {
+        partIdx++;
+        continue;
+      }
+      if (b == '.') {
+        partIdx++;
+        nanoBegin = begin;
+        continue;
+      }
+      if (b < '0' || b > '9') {
+        buf.pos(pos);
+        throw new SQLDataException(
+            String.format(
+                "value '%s' (%s) cannot be decoded as Timestamp",
+                buf.readString(length), dataType));
+      }
+
+      timestampsPart[partIdx] = timestampsPart[partIdx] * 10 + b - 48;
+    }
+    if (timestampsPart[0] == 0
+        && timestampsPart[1] == 0
+        && timestampsPart[2] == 0
+        && timestampsPart[3] == 0
+        && timestampsPart[4] == 0
+        && timestampsPart[5] == 0
+        && timestampsPart[6] == 0) {
+      return null;
+    }
+
+    // fix non-leading tray for nanoseconds
+    if (nanoBegin > 0) {
+      for (int begin = 0; begin < 6 - (length - nanoBegin - 1); begin++) {
+        timestampsPart[6] = timestampsPart[6] * 10;
+      }
+    }
+
+    Timestamp timestamp;
+    if (cal == null) {
+      Calendar c = Calendar.getInstance();
+      c.set(
+          timestampsPart[0],
+          timestampsPart[1] - 1,
+          timestampsPart[2],
+          timestampsPart[3],
+          timestampsPart[4],
+          timestampsPart[5]);
+      timestamp = new Timestamp(c.getTime().getTime());
+      timestamp.setNanos(timestampsPart[6] * 1000);
+    } else {
+      synchronized (cal) {
+        cal.clear();
+        cal.set(
+            timestampsPart[0],
+            timestampsPart[1] - 1,
+            timestampsPart[2],
+            timestampsPart[3],
+            timestampsPart[4],
+            timestampsPart[5]);
+        timestamp = new Timestamp(cal.getTime().getTime());
+        timestamp.setNanos(timestampsPart[6] * 1000);
+      }
+    }
+
+    String st = timestamp.toString();
+    return Date.valueOf(st.substring(0, 10));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+
+    if (length == 0) return null;
+    int year = buf.readUnsignedShort();
+    int month = buf.readByte();
+    int dayOfMonth = buf.readByte();
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+
+    if (length > 4) {
+      hour = buf.readByte();
+      minutes = buf.readByte();
+      seconds = buf.readByte();
+
+      if (length > 7) {
+        microseconds = buf.readUnsignedInt();
+      }
+    }
+
+    // xpand workaround https://jira.mariadb.org/browse/XPT-274
+    if (year == 0
+        && month == 0
+        && dayOfMonth == 0
+        && hour == 0
+        && minutes == 0
+        && seconds == 0
+        && microseconds == 0) return null;
+
+    Timestamp timestamp;
+    synchronized (cal) {
+      cal.clear();
+      cal.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
+      timestamp = new Timestamp(cal.getTimeInMillis());
+    }
+    timestamp.setNanos((int) (microseconds * 1000));
+    String st = timestamp.toString();
+    return Date.valueOf(st.substring(0, 10));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    LocalDateTime lt = LocalDateTimeCodec.INSTANCE.decodeText(buf, length, this, cal);
+    if (lt == null) return null;
+    Calendar cc = cal == null ? Calendar.getInstance() : cal;
+    ZonedDateTime d =
+        TimeCodec.EPOCH_DATE.atTime(lt.toLocalTime()).atZone(cc.getTimeZone().toZoneId());
+    return new Time(d.toEpochSecond() * 1000 + d.getNano() / 1_000_000);
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    if (length == 0) return null;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+
+    int year = buf.readUnsignedShort();
+    int month = buf.readByte();
+    int dayOfMonth = buf.readByte();
+
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+
+    if (length > 4) {
+      hour = buf.readByte();
+      minutes = buf.readByte();
+      seconds = buf.readByte();
+
+      if (length > 7) {
+        microseconds = buf.readUnsignedInt();
+      }
+    }
+
+    if (year == 0 && month == 0 && dayOfMonth == 0 && hour == 0 && minutes == 0 && seconds == 0) {
+      return null;
+    }
+
+    synchronized (cal) {
+      cal.clear();
+      cal.set(1970, Calendar.JANUARY, 1, hour, minutes, seconds);
+      return new Time(cal.getTimeInMillis() + microseconds / 1_000);
+    }
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    int pos = buf.pos();
+    int nanoBegin = -1;
+    int[] timestampsPart = new int[] {0, 0, 0, 0, 0, 0, 0};
+    int partIdx = 0;
+    for (int begin = 0; begin < length; begin++) {
+      byte b = buf.readByte();
+      if (b == '-' || b == ' ' || b == ':') {
+        partIdx++;
+        continue;
+      }
+      if (b == '.') {
+        partIdx++;
+        nanoBegin = begin;
+        continue;
+      }
+      if (b < '0' || b > '9') {
+        buf.pos(pos);
+        throw new SQLDataException(
+            String.format(
+                "value '%s' (%s) cannot be decoded as Timestamp",
+                buf.readString(length), dataType));
+      }
+
+      timestampsPart[partIdx] = timestampsPart[partIdx] * 10 + b - 48;
+    }
+    if (timestampsPart[0] == 0
+        && timestampsPart[1] == 0
+        && timestampsPart[2] == 0
+        && timestampsPart[3] == 0
+        && timestampsPart[4] == 0
+        && timestampsPart[5] == 0
+        && timestampsPart[6] == 0) {
+      return null;
+    }
+
+    // fix non-leading tray for nanoseconds
+    if (nanoBegin > 0) {
+      for (int begin = 0; begin < 6 - (length - nanoBegin - 1); begin++) {
+        timestampsPart[6] = timestampsPart[6] * 10;
+      }
+    }
+
+    Timestamp timestamp;
+    if (calParam == null) {
+      Calendar c = Calendar.getInstance();
+      c.set(
+          timestampsPart[0],
+          timestampsPart[1] - 1,
+          timestampsPart[2],
+          timestampsPart[3],
+          timestampsPart[4],
+          timestampsPart[5]);
+      timestamp = new Timestamp(c.getTime().getTime());
+      timestamp.setNanos(timestampsPart[6] * 1000);
+    } else {
+      synchronized (calParam) {
+        calParam.clear();
+        calParam.set(
+            timestampsPart[0],
+            timestampsPart[1] - 1,
+            timestampsPart[2],
+            timestampsPart[3],
+            timestampsPart[4],
+            timestampsPart[5]);
+        timestamp = new Timestamp(calParam.getTime().getTime());
+        timestamp.setNanos(timestampsPart[6] * 1000);
+      }
+    }
+    return timestamp;
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    if (length == 0) return null;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+
+    int year = buf.readUnsignedShort();
+    int month = buf.readByte();
+    int dayOfMonth = buf.readByte();
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+
+    if (length > 4) {
+      hour = buf.readByte();
+      minutes = buf.readByte();
+      seconds = buf.readByte();
+
+      if (length > 7) {
+        microseconds = buf.readUnsignedInt();
+      }
+    }
+
+    // xpand workaround https://jira.mariadb.org/browse/XPT-274
+    if (year == 0
+        && month == 0
+        && dayOfMonth == 0
+        && hour == 0
+        && minutes == 0
+        && seconds == 0
+        && microseconds == 0) return null;
+    Timestamp timestamp;
+    synchronized (cal) {
+      cal.clear();
+      cal.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
+      timestamp = new Timestamp(cal.getTimeInMillis());
+    }
+    timestamp.setNanos((int) (microseconds * 1000));
+    return timestamp;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/UnsignedBigIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/UnsignedBigIntColumn.java
new file mode 100644
index 0000000..0eb8a72
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/UnsignedBigIntColumn.java
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.math.BigInteger;
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class UnsignedBigIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * BIGINT UNSIGNED metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public UnsignedBigIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return BigInteger.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.BIGINT;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "BIGINT UNSIGNED";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return new BigInteger(buf.readAscii(length));
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    // need BIG ENDIAN, so reverse order
+    byte[] bb = new byte[8];
+    for (int i = 7; i >= 0; i--) {
+      bb[i] = buf.readByte();
+    }
+    return new BigInteger(1, bb);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readLong() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((byte) result != result || result < 0) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    // need BIG ENDIAN, so reverse order
+    byte[] bb = new byte[8];
+    for (int i = 7; i >= 0; i--) {
+      bb[i] = buf.readByte();
+    }
+    BigInteger val = new BigInteger(1, bb);
+    try {
+      return val.byteValueExact();
+    } catch (NumberFormatException | ArithmeticException nfe) {
+      throw new SQLDataException(
+          String.format("value '%s' (%s) cannot be decoded as Byte", val, dataType));
+    }
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    // need BIG ENDIAN, so reverse order
+    byte[] bb = new byte[8];
+    for (int i = 7; i >= 0; i--) {
+      bb[i] = buf.readByte();
+    }
+    return new BigInteger(1, bb).toString();
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((short) result != result || result < 0) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readLong();
+    if ((short) result != result || result < 0) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    int res = (int) result;
+    if (res != result || result < 0) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+
+    // need BIG ENDIAN, so reverse order
+    byte[] bb = new byte[8];
+    for (int i = 7; i >= 0; i--) {
+      bb[i] = buf.readByte();
+    }
+    BigInteger val = new BigInteger(1, bb);
+    try {
+      return val.intValueExact();
+    } catch (ArithmeticException ae) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Integer", val));
+    }
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    if (length < 10) return buf.atoull(length);
+    BigInteger val = new BigInteger(buf.readAscii(length));
+    try {
+      return val.longValueExact();
+    } catch (ArithmeticException ae) {
+      throw new SQLDataException(String.format("value '%s' cannot be decoded as Long", val));
+    }
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    if ((buf.getByte(buf.pos() + 7) & 0x80) == 0) {
+      return buf.readLong();
+    } else {
+      // error too big to return a long
+      byte[] bb = new byte[8];
+      for (int i = 7; i >= 0; i--) {
+        bb[i] = buf.readByte();
+      }
+      BigInteger val = new BigInteger(1, bb);
+      try {
+        return val.longValueExact();
+      } catch (ArithmeticException ae) {
+        throw new SQLDataException(String.format("value '%s' cannot be decoded as Long", val));
+      }
+    }
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    // need BIG ENDIAN, so reverse order
+    byte[] bb = new byte[8];
+    for (int i = 7; i >= 0; i--) {
+      bb[i] = buf.readByte();
+    }
+    return new BigInteger(1, bb).floatValue();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    // need BIG ENDIAN, so reverse order
+    byte[] bb = new byte[8];
+    for (int i = 7; i >= 0; i--) {
+      bb[i] = buf.readByte();
+    }
+    return new BigInteger(1, bb).doubleValue();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/UnsignedIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/UnsignedIntColumn.java
new file mode 100644
index 0000000..00a806d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/UnsignedIntColumn.java
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class UnsignedIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * INTEGER UNSIGNED metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public UnsignedIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Long.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.BIGINT;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "INTEGER UNSIGNED";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.atoull(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.readUnsignedInt();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readInt() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((byte) result != result || (result < 0 && !isSigned())) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readUnsignedInt();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return String.valueOf(buf.readUnsignedInt());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoll(length);
+    if ((short) result != result || result < 0) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readUnsignedInt();
+    if ((short) result != result || result < 0) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    int res = (int) result;
+    if (res != result || result < 0) {
+      throw new SQLDataException("integer overflow");
+    }
+    return res;
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readUnsignedInt();
+    int res = (int) result;
+    if (res != result) {
+      throw new SQLDataException("integer overflow");
+    }
+
+    return res;
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoull(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedInt();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (float) buf.readUnsignedInt();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedInt();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/UnsignedMediumIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/UnsignedMediumIntColumn.java
new file mode 100644
index 0000000..d242941
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/UnsignedMediumIntColumn.java
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class UnsignedMediumIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * MEDIUMINT UNSIGNED metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public UnsignedMediumIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Integer.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.INTEGER;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "MEDIUMINT UNSIGNED";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeIntText(buf, length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return decodeIntBinary(buf, length);
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readInt() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((byte) result != result || result < 0) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readUnsignedMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    String mediumStr = String.valueOf(buf.readUnsignedMedium());
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return mediumStr;
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((short) result != result || result < 0) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readUnsignedMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    if ((short) result != result || result < 0) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (int) buf.atoll(length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    int res = buf.readUnsignedMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return res;
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoull(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long l = buf.readUnsignedMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return l;
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    float f = buf.readUnsignedMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return f;
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    double f = buf.readUnsignedMedium();
+    buf.skip(); // MEDIUMINT is encoded on 4 bytes in exchanges !
+    return f;
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/UnsignedSmallIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/UnsignedSmallIntColumn.java
new file mode 100644
index 0000000..b897671
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/UnsignedSmallIntColumn.java
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class UnsignedSmallIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * SMALLINT UNSIGNED metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public UnsignedSmallIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return Integer.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return Types.INTEGER;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "SMALLINT UNSIGNED";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return (int) buf.atoull(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return buf.readUnsignedShort();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readShort() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((byte) result != result || result < 0) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readUnsignedShort();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return String.valueOf(buf.readUnsignedShort());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    int result = buf.readUnsignedShort();
+    if ((short) result != result) {
+      throw new SQLDataException("Short overflow");
+    }
+    return (short) result;
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (int) buf.atoull(length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedShort();
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoull(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedShort();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (float) buf.readUnsignedShort();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedShort();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/UnsignedTinyIntColumn.java b/src/main/java/org/mariadb/jdbc/client/column/UnsignedTinyIntColumn.java
new file mode 100644
index 0000000..29f3cc1
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/UnsignedTinyIntColumn.java
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+
+/** Column metadata definition */
+public class UnsignedTinyIntColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * TINYINT UNSIGNED metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public UnsignedTinyIntColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    if (conf.tinyInt1isBit() && columnLength == 1) return Boolean.class.getName();
+    return Integer.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return conf.transformedBitIsBoolean() ? Types.BOOLEAN : Types.BIT;
+    }
+    return Types.SMALLINT;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return conf.transformedBitIsBoolean() ? "BOOLEAN" : "BIT";
+    }
+    return "TINYINT UNSIGNED";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return decodeBooleanText(buf, length);
+    }
+    return (int) buf.atoull(length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (conf.tinyInt1isBit() && columnLength == 1) {
+      return decodeBooleanBinary(buf, length);
+    }
+    return (int) buf.readUnsignedByte();
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    String s = buf.readAscii(length);
+    return !"0".equals(s);
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readByte() != 0;
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.atoull(length);
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    long result = buf.readUnsignedByte();
+    if ((byte) result != result) {
+      throw new SQLDataException("byte overflow");
+    }
+    return (byte) result;
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return String.valueOf(buf.readUnsignedByte());
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (short) buf.atoull(length);
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedByte();
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return (int) buf.atoull(length);
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedByte();
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.atoull(length);
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedByte();
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Float.parseFloat(buf.readAscii(length));
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedByte();
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    return Double.parseDouble(buf.readAscii(length));
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    return buf.readUnsignedByte();
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Date", dataType));
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(String.format("Data type %s cannot be decoded as Time", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Timestamp", dataType));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/UuidColumn.java b/src/main/java/org/mariadb/jdbc/client/column/UuidColumn.java
new file mode 100644
index 0000000..2294130
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/UuidColumn.java
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import java.util.UUID;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.server.ColumnDefinitionPacket;
+import org.mariadb.jdbc.util.CharsetEncodingLength;
+
+/** Column metadata definition */
+public class UuidColumn extends ColumnDefinitionPacket implements ColumnDecoder {
+
+  /**
+   * UUID metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public UuidColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return conf.uuidAsString() ? String.class.getName() : UUID.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return conf.uuidAsString() ? Types.CHAR : Types.OTHER;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "uuid";
+  }
+
+  public int getPrecision() {
+    Integer maxWidth = CharsetEncodingLength.maxCharlen.get(charset);
+    if (maxWidth == null) {
+      return (int) columnLength;
+    }
+    return (int) (columnLength / maxWidth);
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return conf.uuidAsString() ? buf.readString(length) : UUID.fromString(buf.readAscii(length));
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    return conf.uuidAsString() ? buf.readString(length) : UUID.fromString(buf.readAscii(length));
+  }
+
+  @Override
+  public boolean decodeBooleanText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Boolean");
+  }
+
+  @Override
+  public boolean decodeBooleanBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Boolean");
+  }
+
+  @Override
+  public byte decodeByteText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as byte");
+  }
+
+  @Override
+  public byte decodeByteBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as byte");
+  }
+
+  @Override
+  public String decodeStringText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public String decodeStringBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    return buf.readString(length);
+  }
+
+  @Override
+  public short decodeShortText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Short");
+  }
+
+  @Override
+  public short decodeShortBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Short");
+  }
+
+  @Override
+  public int decodeIntText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Integer");
+  }
+
+  @Override
+  public int decodeIntBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Integer");
+  }
+
+  @Override
+  public long decodeLongText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Long");
+  }
+
+  @Override
+  public long decodeLongBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Long");
+  }
+
+  @Override
+  public float decodeFloatText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Float");
+  }
+
+  @Override
+  public float decodeFloatBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Float");
+  }
+
+  @Override
+  public double decodeDoubleText(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Double");
+  }
+
+  @Override
+  public double decodeDoubleBinary(ReadableByteBuf buf, int length) throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Double");
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Date");
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Date");
+  }
+
+  @Override
+  public Time decodeTimeText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Time");
+  }
+
+  @Override
+  public Time decodeTimeBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Time");
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Timestamp");
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    buf.skip(length);
+    throw new SQLDataException("Data type UUID cannot be decoded as Timestamp");
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/column/YearColumn.java b/src/main/java/org/mariadb/jdbc/client/column/YearColumn.java
new file mode 100644
index 0000000..1985d85
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/column/YearColumn.java
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.column;
+
+import java.sql.*;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+
+/** Column metadata definition */
+public class YearColumn extends UnsignedSmallIntColumn {
+
+  /**
+   * YEAR metadata type decoder
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param length maximum data length
+   * @param dataType data type. see https://mariadb.com/kb/en/result-set-packets/#field-types
+   * @param decimals decimal length
+   * @param flags flags. see https://mariadb.com/kb/en/result-set-packets/#field-details-flag
+   * @param stringPos string offset position in buffer
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public YearColumn(
+      ReadableByteBuf buf,
+      int charset,
+      long length,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    super(buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
+  }
+
+  public String defaultClassname(Configuration conf) {
+    return conf.yearIsDateType() ? Date.class.getName() : Short.class.getName();
+  }
+
+  public int getColumnType(Configuration conf) {
+    return conf.yearIsDateType() ? Types.DATE : Types.SMALLINT;
+  }
+
+  public String getColumnTypeName(Configuration conf) {
+    return "YEAR";
+  }
+
+  @Override
+  public Object getDefaultText(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (conf.yearIsDateType()) {
+      short y = (short) buf.atoull(length);
+      if (columnLength == 2) {
+        // YEAR(2) - deprecated
+        if (y <= 69) {
+          y += 2000;
+        } else {
+          y += 1900;
+        }
+      }
+      return Date.valueOf(y + "-01-01");
+    }
+    return decodeShortText(buf, length);
+  }
+
+  @Override
+  public Object getDefaultBinary(final Configuration conf, ReadableByteBuf buf, int length)
+      throws SQLDataException {
+    if (conf.yearIsDateType()) {
+      int v = buf.readShort();
+      if (columnLength == 2) {
+        // YEAR(2) - deprecated
+        if (v <= 69) {
+          v += 2000;
+        } else {
+          v += 1900;
+        }
+      }
+      return Date.valueOf(v + "-01-01");
+    }
+    return decodeShortText(buf, length);
+  }
+
+  @Override
+  public Date decodeDateText(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    short y = (short) buf.atoll(length);
+    if (columnLength == 2) {
+      // YEAR(2) - deprecated
+      if (y <= 69) {
+        y += 2000;
+      } else {
+        y += 1900;
+      }
+    }
+    return Date.valueOf(y + "-01-01");
+  }
+
+  @Override
+  public Date decodeDateBinary(ReadableByteBuf buf, int length, Calendar cal)
+      throws SQLDataException {
+    int v = buf.readShort();
+
+    if (columnLength == 2) {
+      // YEAR(2) - deprecated
+      if (v <= 69) {
+        v += 2000;
+      } else {
+        v += 1900;
+      }
+    }
+    return Date.valueOf(v + "-01-01");
+  }
+
+  @Override
+  public Timestamp decodeTimestampText(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    Calendar cal1 = calParam == null ? Calendar.getInstance() : calParam;
+
+    int year = Integer.parseInt(buf.readAscii(length));
+    if (columnLength <= 2) year += year >= 70 ? 1900 : 2000;
+    synchronized (cal1) {
+      cal1.clear();
+      cal1.set(year, Calendar.JANUARY, 1);
+      return new Timestamp(cal1.getTimeInMillis());
+    }
+  }
+
+  @Override
+  public Timestamp decodeTimestampBinary(ReadableByteBuf buf, int length, Calendar calParam)
+      throws SQLDataException {
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+
+    int year = buf.readUnsignedShort();
+    if (columnLength <= 2) year += year >= 70 ? 1900 : 2000;
+
+    Timestamp timestamp;
+    synchronized (cal) {
+      cal.clear();
+      cal.set(year, 0, 1, 0, 0, 0);
+      timestamp = new Timestamp(cal.getTimeInMillis());
+    }
+    timestamp.setNanos(0);
+    return timestamp;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/context/BaseContext.java b/src/main/java/org/mariadb/jdbc/client/context/BaseContext.java
new file mode 100644
index 0000000..3645d1e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/context/BaseContext.java
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.context;
+
+import static org.mariadb.jdbc.util.constants.Capabilities.STMT_BULK_OPERATIONS;
+
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.PrepareCache;
+import org.mariadb.jdbc.client.ServerVersion;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.server.InitialHandshakePacket;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+/** Context (current connection state) of a connection */
+public class BaseContext implements Context {
+
+  private final long threadId;
+  private final long serverCapabilities;
+  private final long clientCapabilities;
+  private final byte[] seed;
+  private final ServerVersion version;
+  private final boolean eofDeprecated;
+  private final boolean skipMeta;
+  private final boolean extendedInfo;
+  private final Configuration conf;
+  private final ExceptionFactory exceptionFactory;
+
+  /** Server status context */
+  protected int serverStatus;
+
+  /** Server current database */
+  private String database;
+
+  /** Server current transaction isolation level */
+  private int transactionIsolationLevel;
+
+  /** Server current warning count */
+  private int warning;
+
+  /** LRU prepare cache object */
+  private final PrepareCache prepareCache;
+
+  /** Connection state use flag */
+  private int stateFlag = 0;
+
+  /**
+   * Constructor of connection context
+   *
+   * @param handshake server handshake
+   * @param clientCapabilities client capabilities
+   * @param conf connection configuration
+   * @param exceptionFactory connection exception factory
+   * @param prepareCache LRU prepare cache
+   */
+  public BaseContext(
+      InitialHandshakePacket handshake,
+      long clientCapabilities,
+      Configuration conf,
+      ExceptionFactory exceptionFactory,
+      PrepareCache prepareCache) {
+    this.threadId = handshake.getThreadId();
+    this.seed = handshake.getSeed();
+    this.serverCapabilities = handshake.getCapabilities();
+    this.serverStatus = handshake.getServerStatus();
+    this.version = handshake.getVersion();
+    this.clientCapabilities = clientCapabilities;
+    this.eofDeprecated = hasClientCapability(Capabilities.CLIENT_DEPRECATE_EOF);
+    this.skipMeta = hasClientCapability(Capabilities.CACHE_METADATA);
+    this.extendedInfo = hasClientCapability(Capabilities.EXTENDED_TYPE_INFO);
+    this.conf = conf;
+    this.database = conf.database();
+    this.exceptionFactory = exceptionFactory;
+    this.prepareCache = prepareCache;
+  }
+
+  public long getThreadId() {
+    return threadId;
+  }
+
+  public byte[] getSeed() {
+    return seed;
+  }
+
+  public boolean hasServerCapability(long flag) {
+    return (serverCapabilities & flag) > 0;
+  }
+
+  public boolean hasClientCapability(long flag) {
+    return (clientCapabilities & flag) > 0;
+  }
+
+  public boolean permitPipeline() {
+    return !conf.disablePipeline() && (clientCapabilities & STMT_BULK_OPERATIONS) > 0;
+  }
+
+  public int getServerStatus() {
+    return serverStatus;
+  }
+
+  public void setServerStatus(int serverStatus) {
+    this.serverStatus = serverStatus;
+  }
+
+  public String getDatabase() {
+    return database;
+  }
+
+  public void setDatabase(String database) {
+    this.database = database;
+  }
+
+  public ServerVersion getVersion() {
+    return version;
+  }
+
+  public boolean isEofDeprecated() {
+    return eofDeprecated;
+  }
+
+  public boolean isExtendedInfo() {
+    return extendedInfo;
+  }
+
+  public boolean canSkipMeta() {
+    return skipMeta;
+  }
+
+  public int getWarning() {
+    return warning;
+  }
+
+  public void setWarning(int warning) {
+    this.warning = warning;
+  }
+
+  public ExceptionFactory getExceptionFactory() {
+    return exceptionFactory;
+  }
+
+  public Configuration getConf() {
+    return conf;
+  }
+
+  public int getTransactionIsolationLevel() {
+    return transactionIsolationLevel;
+  }
+
+  public void setTransactionIsolationLevel(int transactionIsolationLevel) {
+    this.transactionIsolationLevel = transactionIsolationLevel;
+  }
+
+  public PrepareCache getPrepareCache() {
+    return prepareCache;
+  }
+
+  public void resetPrepareCache() {
+    if (prepareCache != null) prepareCache.reset();
+  }
+
+  public int getStateFlag() {
+    return stateFlag;
+  }
+
+  public void resetStateFlag() {
+    stateFlag = 0;
+  }
+
+  public void addStateFlag(int state) {
+    stateFlag |= state;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/context/RedoContext.java b/src/main/java/org/mariadb/jdbc/client/context/RedoContext.java
new file mode 100644
index 0000000..dd809ab
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/context/RedoContext.java
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.context;
+
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.PrepareCache;
+import org.mariadb.jdbc.client.impl.TransactionSaver;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.client.RedoableClientMessage;
+import org.mariadb.jdbc.message.server.InitialHandshakePacket;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Redo addition to Context */
+public class RedoContext extends BaseContext {
+
+  private final TransactionSaver transactionSaver;
+
+  /**
+   * Constructor
+   *
+   * @param handshake server handshake
+   * @param clientCapabilities client capabilities
+   * @param conf configuration
+   * @param exceptionFactory connection exception factory
+   * @param prepareCache LRU prepare cache
+   */
+  public RedoContext(
+      InitialHandshakePacket handshake,
+      long clientCapabilities,
+      Configuration conf,
+      ExceptionFactory exceptionFactory,
+      PrepareCache prepareCache) {
+    super(handshake, clientCapabilities, conf, exceptionFactory, prepareCache);
+    this.transactionSaver = new TransactionSaver(conf.transactionReplaySize());
+  }
+
+  /**
+   * Set server status
+   *
+   * @param serverStatus server status
+   */
+  public void setServerStatus(int serverStatus) {
+    this.serverStatus = serverStatus;
+    if ((serverStatus & ServerStatus.IN_TRANSACTION) == 0) transactionSaver.clear();
+  }
+
+  /**
+   * Save client message
+   *
+   * @param msg client message
+   */
+  public void saveRedo(ClientMessage msg) {
+    if (msg instanceof RedoableClientMessage) {
+      RedoableClientMessage redoMsg = (RedoableClientMessage) msg;
+      redoMsg.saveParameters();
+      transactionSaver.add(redoMsg);
+    }
+  }
+
+  /**
+   * Save client messages
+   *
+   * @param msgs client messages
+   */
+  public void saveRedo(ClientMessage[] msgs) {
+    for (ClientMessage msg : msgs) saveRedo(msg);
+  }
+
+  /**
+   * Get transaction saver cache
+   *
+   * @return transaction saver cache
+   */
+  public TransactionSaver getTransactionSaver() {
+    return transactionSaver;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/ConnectionHelper.java b/src/main/java/org/mariadb/jdbc/client/impl/ConnectionHelper.java
new file mode 100644
index 0000000..514a117
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/ConnectionHelper.java
@@ -0,0 +1,450 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.sql.SQLException;
+import java.sql.SQLNonTransientConnectionException;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.SocketHelper;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.socket.impl.SocketHandlerFunction;
+import org.mariadb.jdbc.client.socket.impl.SocketUtility;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.message.client.SslRequestPacket;
+import org.mariadb.jdbc.message.server.AuthSwitchPacket;
+import org.mariadb.jdbc.message.server.ErrorPacket;
+import org.mariadb.jdbc.message.server.InitialHandshakePacket;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+import org.mariadb.jdbc.plugin.Credential;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+import org.mariadb.jdbc.plugin.TlsSocketPlugin;
+import org.mariadb.jdbc.plugin.authentication.AuthenticationPluginLoader;
+import org.mariadb.jdbc.plugin.tls.TlsSocketPluginLoader;
+import org.mariadb.jdbc.util.ConfigurableSocketFactory;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+/** Connection creation helper class */
+public final class ConnectionHelper {
+
+  private static final SocketHandlerFunction socketHandler;
+
+  static {
+    SocketHandlerFunction init;
+    try {
+      init = SocketUtility.getSocketHandler();
+    } catch (Throwable t) {
+      init = ConnectionHelper::standardSocket;
+    }
+    socketHandler = init;
+  }
+
+  /**
+   * Create socket accordingly to options.
+   *
+   * @param conf Url options
+   * @param hostAddress host ( mandatory but for named pipe / unix socket)
+   * @return a nex socket
+   * @throws IOException if connection error occur
+   * @throws SQLException in case of configuration error
+   */
+  public static Socket createSocket(Configuration conf, HostAddress hostAddress)
+      throws IOException, SQLException {
+    return socketHandler.apply(conf, hostAddress);
+  }
+
+  /**
+   * Use standard socket implementation.
+   *
+   * @param conf url options
+   * @param hostAddress host to connect
+   * @return socket
+   * @throws IOException in case of error establishing socket.
+   * @throws SQLException in case host is null
+   */
+  public static Socket standardSocket(Configuration conf, HostAddress hostAddress)
+      throws IOException, SQLException {
+    SocketFactory socketFactory;
+    String socketFactoryName = conf.socketFactory();
+    if (socketFactoryName != null) {
+      if (hostAddress == null) throw new SQLException("hostname must be set to connect socket");
+      try {
+        @SuppressWarnings("unchecked")
+        Class<? extends SocketFactory> socketFactoryClass =
+            (Class<? extends SocketFactory>) Class.forName(socketFactoryName);
+        Constructor<? extends SocketFactory> constructor = socketFactoryClass.getConstructor();
+        socketFactory = constructor.newInstance();
+        if (socketFactory instanceof ConfigurableSocketFactory) {
+          ((ConfigurableSocketFactory) socketFactory).setConfiguration(conf, hostAddress.host);
+        }
+        return socketFactory.createSocket();
+      } catch (Exception exp) {
+        throw new IOException(
+            "Socket factory failed to initialized with option \"socketFactory\" set to \""
+                + conf.socketFactory()
+                + "\"",
+            exp);
+      }
+    }
+    socketFactory = SocketFactory.getDefault();
+    return socketFactory.createSocket();
+  }
+
+  /**
+   * Connect socket
+   *
+   * @param conf configuration
+   * @param hostAddress host to connect
+   * @return socket
+   * @throws SQLException if hostname is required and not provided, or socket cannot be created
+   */
+  public static Socket connectSocket(final Configuration conf, final HostAddress hostAddress)
+      throws SQLException {
+    Socket socket;
+    try {
+      if (conf.pipe() == null && conf.localSocket() == null && hostAddress == null)
+        throw new SQLException(
+            "hostname must be set to connect socket if not using local socket or pipe");
+      socket = createSocket(conf, hostAddress);
+      SocketHelper.setSocketOption(conf, socket);
+      if (!socket.isConnected()) {
+        InetSocketAddress sockAddr =
+            conf.pipe() == null && conf.localSocket() == null
+                ? new InetSocketAddress(hostAddress.host, hostAddress.port)
+                : null;
+        socket.connect(sockAddr, conf.connectTimeout());
+      }
+      return socket;
+
+    } catch (IOException ioe) {
+      throw new SQLNonTransientConnectionException(
+          String.format(
+              "Socket fail to connect to host:%s. %s",
+              hostAddress == null ? conf.localSocket() : hostAddress, ioe.getMessage()),
+          "08000",
+          ioe);
+    }
+  }
+
+  /**
+   * Initialize client capability according to configuration and server capabilities.
+   *
+   * @param configuration configuration
+   * @param serverCapabilities server capabilities
+   * @param hostAddress host address server
+   * @return client capabilities
+   */
+  public static long initializeClientCapabilities(
+      final Configuration configuration,
+      final long serverCapabilities,
+      final HostAddress hostAddress) {
+    long capabilities =
+        Capabilities.IGNORE_SPACE
+            | Capabilities.CLIENT_PROTOCOL_41
+            | Capabilities.TRANSACTIONS
+            | Capabilities.SECURE_CONNECTION
+            | Capabilities.MULTI_RESULTS
+            | Capabilities.PS_MULTI_RESULTS
+            | Capabilities.PLUGIN_AUTH
+            | Capabilities.CONNECT_ATTRS
+            | Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA
+            | Capabilities.CLIENT_SESSION_TRACK
+            | Capabilities.EXTENDED_TYPE_INFO;
+
+    // since skipping metadata is only available when using binary protocol,
+    // only set it when server permit it and using binary protocol
+    if (configuration.useServerPrepStmts()
+        && Boolean.parseBoolean(
+            configuration.nonMappedOptions().getProperty("enableSkipMeta", "true"))) {
+      capabilities |= Capabilities.CACHE_METADATA;
+    }
+
+    // remains for compatibility
+    if (Boolean.parseBoolean(
+        configuration.nonMappedOptions().getProperty("interactiveClient", "false"))) {
+      capabilities |= Capabilities.CLIENT_INTERACTIVE;
+    }
+
+    if (configuration.useBulkStmts()) {
+      capabilities |= Capabilities.STMT_BULK_OPERATIONS;
+    }
+
+    if (!configuration.useAffectedRows()) {
+      capabilities |= Capabilities.FOUND_ROWS;
+    }
+
+    if (configuration.allowMultiQueries()) {
+      capabilities |= Capabilities.MULTI_STATEMENTS;
+    }
+
+    if (configuration.allowLocalInfile()) {
+      capabilities |= Capabilities.LOCAL_FILES;
+    }
+
+    // useEof is a technical option
+    boolean deprecateEof =
+        Boolean.parseBoolean(configuration.nonMappedOptions().getProperty("deprecateEof", "true"));
+    if (deprecateEof) {
+      capabilities |= Capabilities.CLIENT_DEPRECATE_EOF;
+    }
+
+    if (configuration.useCompression()) {
+      capabilities |= Capabilities.COMPRESS;
+    }
+
+    // connect to database directly if not needed to be created, or if slave, since cannot be
+    // created
+    if (configuration.database() != null
+        && (!configuration.createDatabaseIfNotExist()
+            || (configuration.createDatabaseIfNotExist()
+                && (hostAddress != null && !hostAddress.primary)))) {
+      capabilities |= Capabilities.CONNECT_WITH_DB;
+    }
+
+    if (configuration.sslMode() != SslMode.DISABLE) {
+      capabilities |= Capabilities.SSL;
+    }
+    return capabilities & serverCapabilities;
+  }
+
+  /**
+   * Default collation used for string exchanges with server. Always return 4 bytes utf8 collation
+   * for server that permit it.
+   *
+   * @param handshake initial handshake packet
+   * @return collation byte
+   */
+  public static byte decideLanguage(InitialHandshakePacket handshake) {
+    short serverLanguage = handshake.getDefaultCollation();
+    // return current server utf8mb4 collation
+    return (byte)
+        ((serverLanguage == 45 // utf8mb4_general_ci
+                || serverLanguage == 46 // utf8mb4_bin
+                || (serverLanguage >= 224 && serverLanguage <= 247))
+            ? serverLanguage
+            : 224); // UTF8MB4_UNICODE_CI;
+  }
+
+  /**
+   * Authentication swtich handler
+   *
+   * @param credential credential
+   * @param writer socket writer
+   * @param reader socket reader
+   * @param context connection context
+   * @throws IOException if any socket error occurs
+   * @throws SQLException if any other kind of issue occurs
+   */
+  public static void authenticationHandler(
+      Credential credential, Writer writer, Reader reader, Context context)
+      throws IOException, SQLException {
+
+    writer.permitTrace(true);
+    Configuration conf = context.getConf();
+    ReadableByteBuf buf = reader.readReusablePacket();
+
+    authentication_loop:
+    while (true) {
+      switch (buf.getByte() & 0xFF) {
+        case 0xFE:
+          // *************************************************************************************
+          // Authentication Switch Request see
+          // https://mariadb.com/kb/en/library/connection/#authentication-switch-request
+          // *************************************************************************************
+          AuthSwitchPacket authSwitchPacket = AuthSwitchPacket.decode(buf);
+          AuthenticationPlugin authenticationPlugin =
+              AuthenticationPluginLoader.get(authSwitchPacket.getPlugin(), conf);
+
+          authenticationPlugin.initialize(
+              credential.getPassword(), authSwitchPacket.getSeed(), conf);
+          buf = authenticationPlugin.process(writer, reader, context);
+          break;
+
+        case 0xFF:
+          // *************************************************************************************
+          // ERR_Packet
+          // see https://mariadb.com/kb/en/library/err_packet/
+          // *************************************************************************************
+          ErrorPacket errorPacket = new ErrorPacket(buf, context);
+          throw context
+              .getExceptionFactory()
+              .create(
+                  errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
+
+        case 0x00:
+          // *************************************************************************************
+          // OK_Packet -> Authenticated !
+          // see https://mariadb.com/kb/en/library/ok_packet/
+          // *************************************************************************************
+          buf.skip(); // 0x00 OkPacket Header
+          buf.readLongLengthEncodedNotNull(); // skip affectedRows
+          buf.readLongLengthEncodedNotNull(); // skip insert id
+          // insertId
+          context.setServerStatus(buf.readShort());
+          break authentication_loop;
+
+        default:
+          throw context
+              .getExceptionFactory()
+              .create(
+                  "unexpected data during authentication (header=" + (buf.getUnsignedByte()),
+                  "08000");
+      }
+    }
+    writer.permitTrace(true);
+  }
+
+  /**
+   * Load user/password plugin if configured to.
+   *
+   * @param credentialPlugin configuration credential plugin
+   * @param configuration configuration
+   * @param hostAddress current connection host address
+   * @return credentials
+   * @throws SQLException if configured credential plugin fail
+   */
+  public static Credential loadCredential(
+      CredentialPlugin credentialPlugin, Configuration configuration, HostAddress hostAddress)
+      throws SQLException {
+    if (credentialPlugin != null) {
+      return credentialPlugin.initialize(configuration, configuration.user(), hostAddress).get();
+    }
+    return new Credential(configuration.user(), configuration.password());
+  }
+
+  /**
+   * Create SSL wrapper
+   *
+   * @param hostAddress host
+   * @param socket socket
+   * @param clientCapabilities client capabilities
+   * @param exchangeCharset connection charset
+   * @param context connection context
+   * @param writer socket writer
+   * @return SSLsocket
+   * @throws IOException if any socket error occurs
+   * @throws SQLException for any other kind of error
+   */
+  public static SSLSocket sslWrapper(
+      final HostAddress hostAddress,
+      final Socket socket,
+      long clientCapabilities,
+      final byte exchangeCharset,
+      Context context,
+      Writer writer)
+      throws IOException, SQLException {
+
+    Configuration conf = context.getConf();
+    if (conf.sslMode() != SslMode.DISABLE) {
+
+      if (!context.hasServerCapability(Capabilities.SSL)) {
+        throw context
+            .getExceptionFactory()
+            .create("Trying to connect with ssl, but ssl not enabled in the server", "08000");
+      }
+
+      clientCapabilities |= Capabilities.SSL;
+      SslRequestPacket.create(clientCapabilities, exchangeCharset).encode(writer, context);
+
+      TlsSocketPlugin socketPlugin = TlsSocketPluginLoader.get(conf.tlsSocketType());
+      SSLSocketFactory sslSocketFactory =
+          socketPlugin.getSocketFactory(conf, context.getExceptionFactory());
+      SSLSocket sslSocket = socketPlugin.createSocket(socket, sslSocketFactory);
+
+      enabledSslProtocolSuites(sslSocket, conf);
+      enabledSslCipherSuites(sslSocket, conf);
+
+      sslSocket.setUseClientMode(true);
+      sslSocket.startHandshake();
+
+      // perform hostname verification
+      // (rfc2818 indicate that if "client has external information as to the expected identity of
+      // the server, the hostname check MAY be omitted")
+      if (conf.sslMode() == SslMode.VERIFY_FULL && hostAddress != null) {
+
+        SSLSession session = sslSocket.getSession();
+        try {
+          socketPlugin.verify(hostAddress.host, session, context.getThreadId());
+        } catch (SSLException ex) {
+          throw context
+              .getExceptionFactory()
+              .create(
+                  "SSL hostname verification failed : "
+                      + ex.getMessage()
+                      + "\nThis verification can be disabled using the sslMode to VERIFY_CA "
+                      + "but won't prevent man-in-the-middle attacks anymore",
+                  "08006");
+        }
+      }
+      return sslSocket;
+    }
+    return null;
+  }
+
+  /**
+   * Return possible protocols : values of option enabledSslProtocolSuites is set, or default to
+   * "TLSv1,TLSv1.1". MariaDB versions &ge; 10.0.15 and &ge; 5.5.41 supports TLSv1.2 if compiled
+   * with openSSL (default). MySQL's community versions &ge; 5.7.10 is compiled with yaSSL, so max
+   * TLS is TLSv1.1.
+   *
+   * @param sslSocket current sslSocket
+   * @throws SQLException if protocol isn't a supported protocol
+   */
+  static void enabledSslProtocolSuites(SSLSocket sslSocket, Configuration conf)
+      throws SQLException {
+    if (conf.enabledSslProtocolSuites() != null) {
+      List<String> possibleProtocols = Arrays.asList(sslSocket.getSupportedProtocols());
+      String[] protocols = conf.enabledSslProtocolSuites().split("[,;\\s]+");
+      for (String protocol : protocols) {
+        if (!possibleProtocols.contains(protocol)) {
+          throw new SQLException(
+              "Unsupported SSL protocol '"
+                  + protocol
+                  + "'. Supported protocols : "
+                  + possibleProtocols.toString().replace("[", "").replace("]", ""));
+        }
+      }
+      sslSocket.setEnabledProtocols(protocols);
+    }
+  }
+
+  /**
+   * Set ssl socket cipher according to options.
+   *
+   * @param sslSocket current ssl socket
+   * @param conf configuration
+   * @throws SQLException if a cipher isn't known
+   */
+  static void enabledSslCipherSuites(SSLSocket sslSocket, Configuration conf) throws SQLException {
+    if (conf.enabledSslCipherSuites() != null) {
+      List<String> possibleCiphers = Arrays.asList(sslSocket.getSupportedCipherSuites());
+      String[] ciphers = conf.enabledSslCipherSuites().split("[,;\\s]+");
+      for (String cipher : ciphers) {
+        if (!possibleCiphers.contains(cipher)) {
+          throw new SQLException(
+              "Unsupported SSL cipher '"
+                  + cipher
+                  + "'. Supported ciphers : "
+                  + possibleCiphers.toString().replace("[", "").replace("]", ""));
+        }
+      }
+      sslSocket.setEnabledCipherSuites(ciphers);
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/MultiPrimaryClient.java b/src/main/java/org/mariadb/jdbc/client/impl/MultiPrimaryClient.java
new file mode 100644
index 0000000..6f90c1d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/MultiPrimaryClient.java
@@ -0,0 +1,552 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.sql.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.context.RedoContext;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.client.ChangeDbPacket;
+import org.mariadb.jdbc.message.client.QueryPacket;
+import org.mariadb.jdbc.message.client.RedoableWithPrepareClientMessage;
+import org.mariadb.jdbc.util.constants.ConnectionState;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/**
+ * Handling connection failing automatic reconnection transparently when possible for multi-master
+ * Topology.
+ *
+ * <p>remark: would have been better using proxy, but for AOT compilation, avoiding to using not
+ * supported proxy class.
+ */
+public class MultiPrimaryClient implements Client {
+  private static final Logger logger = Loggers.getLogger(MultiPrimaryClient.class);
+
+  /** temporary blacklisted hosts */
+  protected static final ConcurrentMap<HostAddress, Long> denyList = new ConcurrentHashMap<>();
+
+  /** denied timeout */
+  protected final long deniedListTimeout;
+
+  /** configuration */
+  protected final Configuration conf;
+
+  /** is connections explicitly closed */
+  protected boolean closed = false;
+
+  /** thread locker */
+  protected final ReentrantLock lock;
+
+  /** current client */
+  protected Client currentClient;
+
+  /**
+   * Constructor
+   *
+   * @param conf configuration
+   * @param lock thread locker
+   * @throws SQLException if fail to connect
+   */
+  public MultiPrimaryClient(Configuration conf, ReentrantLock lock) throws SQLException {
+    this.conf = conf;
+    this.lock = lock;
+    deniedListTimeout =
+        Long.parseLong(conf.nonMappedOptions().getProperty("deniedListTimeout", "60000"));
+    currentClient = connectHost(false, false);
+  }
+
+  /**
+   * Trying connecting server.
+   *
+   * <p>searching each connecting primary / replica connection not temporary denied until found one.
+   * searching in temporary denied host if not succeed, until reaching `retriesAllDown` attempts.
+   *
+   * @param readOnly must connect a replica / primary
+   * @param failFast must try only not denied server
+   * @return a valid connection client
+   * @throws SQLException if not succeed to create a connection.
+   */
+  protected Client connectHost(boolean readOnly, boolean failFast) throws SQLException {
+
+    Optional<HostAddress> host;
+    SQLNonTransientConnectionException lastSqle = null;
+    int maxRetries = conf.retriesAllDown();
+
+    while ((host = conf.haMode().getAvailableHost(conf.addresses(), denyList, !readOnly))
+            .isPresent()
+        && maxRetries > 0) {
+
+      try {
+        return conf.transactionReplay()
+            ? new ReplayClient(conf, host.get(), lock, false)
+            : new StandardClient(conf, host.get(), lock, false);
+      } catch (SQLNonTransientConnectionException sqle) {
+        lastSqle = sqle;
+        denyList.putIfAbsent(host.get(), System.currentTimeMillis() + deniedListTimeout);
+        maxRetries--;
+      }
+    }
+
+    if (failFast) {
+      throw (lastSqle != null)
+          ? lastSqle
+          : new SQLNonTransientConnectionException("all hosts are blacklisted");
+    }
+
+    // All server corresponding to type are in deny list
+    // return the one with lower denylist timeout
+    // (check that server is in conf, because denyList is shared for all instances)
+    if (denyList.entrySet().stream()
+        .noneMatch(e -> conf.addresses().contains(e.getKey()) && e.getKey().primary != readOnly))
+      throw new SQLNonTransientConnectionException(
+          String.format("No %s host defined", readOnly ? "replica" : "primary"));
+    while (maxRetries > 0) {
+      try {
+        host =
+            denyList.entrySet().stream()
+                .sorted(Map.Entry.comparingByValue())
+                .filter(
+                    e -> conf.addresses().contains(e.getKey()) && e.getKey().primary != readOnly)
+                .findFirst()
+                .map(Map.Entry::getKey);
+        if (host.isPresent()) {
+          Client client =
+              conf.transactionReplay()
+                  ? new ReplayClient(conf, host.get(), lock, false)
+                  : new StandardClient(conf, host.get(), lock, false);
+          denyList.remove(host.get());
+          return client;
+        }
+        maxRetries--;
+      } catch (SQLNonTransientConnectionException sqle) {
+        lastSqle = sqle;
+        host.ifPresent(
+            hostAddress ->
+                denyList.putIfAbsent(hostAddress, System.currentTimeMillis() + deniedListTimeout));
+        maxRetries--;
+        if (maxRetries > 0) {
+          try {
+            // wait 250ms before looping through
+            Thread.sleep(250);
+          } catch (InterruptedException interrupted) {
+            // interrupted, continue
+          }
+        }
+      }
+    }
+
+    throw lastSqle;
+  }
+
+  /**
+   * Connection loop
+   *
+   * @return client connection
+   * @throws SQLException if fail to connect
+   */
+  protected Client reConnect() throws SQLException {
+
+    denyList.putIfAbsent(
+        currentClient.getHostAddress(), System.currentTimeMillis() + deniedListTimeout);
+    logger.info("Connection error on {}", currentClient.getHostAddress());
+    try {
+      Client oldClient = currentClient;
+      // remove cached prepare from existing server prepare statement
+      oldClient.getContext().resetPrepareCache();
+
+      currentClient = connectHost(false, false);
+      syncNewState(oldClient);
+      return oldClient;
+
+    } catch (SQLNonTransientConnectionException sqle) {
+      currentClient = null;
+      closed = true;
+      throw sqle;
+    }
+  }
+
+  /**
+   * Execute transaction replay if in transaction and configured for it, throw an exception if not
+   *
+   * @param oldClient previous client
+   * @param canRedo if command can be redo even if not in transaction
+   * @throws SQLException if not able to replay
+   */
+  protected void replayIfPossible(Client oldClient, boolean canRedo) throws SQLException {
+    // oldClient is only valued if this occurs on master.
+    if (oldClient != null) {
+      if ((oldClient.getContext().getServerStatus() & ServerStatus.IN_TRANSACTION) > 0) {
+        if (conf.transactionReplay()) {
+          executeTransactionReplay(oldClient);
+        } else {
+          // transaction is lost, but connection is now up again.
+          // changing exception to SQLTransientConnectionException
+          throw new SQLTransientConnectionException(
+              String.format(
+                  "Driver has reconnect connection after a communications link failure with %s. In"
+                      + " progress transaction was lost",
+                  oldClient.getHostAddress()),
+              "25S03");
+        }
+      } else if (!canRedo) {
+        // no transaction, but connection is now up again.
+        // changing exception to SQLTransientConnectionException
+        throw new SQLTransientConnectionException(
+            String.format(
+                "Driver has reconnect connection after a communications link failure with %s",
+                oldClient.getHostAddress()),
+            "25S03");
+      }
+    }
+  }
+
+  /**
+   * Execute transaction replay
+   *
+   * @param oldCli previous client
+   * @throws SQLException if not able to replay
+   */
+  protected void executeTransactionReplay(Client oldCli) throws SQLException {
+    // transaction replay
+    RedoContext ctx = (RedoContext) oldCli.getContext();
+    if (ctx.getTransactionSaver().isDirty()) {
+      ctx.getTransactionSaver().clear();
+      throw new SQLTransientConnectionException(
+          String.format(
+              "Driver has reconnect connection after a communications link failure with %s. In"
+                  + " progress transaction was too big to be replayed, and was lost",
+              oldCli.getHostAddress()),
+          "25S03");
+    }
+    ((ReplayClient) currentClient).transactionReplay(ctx.getTransactionSaver());
+  }
+
+  /**
+   * Synchronized previous and new client states.
+   *
+   * @param oldCli previous client
+   * @throws SQLException if error occurs
+   */
+  public void syncNewState(Client oldCli) throws SQLException {
+    Context oldCtx = oldCli.getContext();
+    currentClient.getExceptionFactory().setConnection(oldCli.getExceptionFactory());
+    if ((oldCtx.getStateFlag() & ConnectionState.STATE_AUTOCOMMIT) > 0) {
+      if ((oldCtx.getServerStatus() & ServerStatus.AUTOCOMMIT)
+          != (currentClient.getContext().getServerStatus() & ServerStatus.AUTOCOMMIT)) {
+        currentClient.getContext().addStateFlag(ConnectionState.STATE_AUTOCOMMIT);
+        currentClient.execute(
+            new QueryPacket(
+                "set autocommit="
+                    + (((oldCtx.getServerStatus() & ServerStatus.AUTOCOMMIT) > 0) ? "1" : "0")),
+            true);
+      }
+    }
+
+    if ((oldCtx.getStateFlag() & ConnectionState.STATE_DATABASE) > 0
+        && !Objects.equals(currentClient.getContext().getDatabase(), oldCtx.getDatabase())) {
+      currentClient.getContext().addStateFlag(ConnectionState.STATE_DATABASE);
+      if (oldCtx.getDatabase() != null) {
+        currentClient.execute(new ChangeDbPacket(oldCtx.getDatabase()), true);
+      }
+      currentClient.getContext().setDatabase(oldCtx.getDatabase());
+    }
+
+    if ((oldCtx.getStateFlag() & ConnectionState.STATE_NETWORK_TIMEOUT) > 0) {
+      currentClient.setSocketTimeout(oldCli.getSocketTimeout());
+    }
+
+    if ((oldCtx.getStateFlag() & ConnectionState.STATE_READ_ONLY) > 0
+        && !currentClient.getHostAddress().primary
+        && currentClient.getContext().getVersion().versionGreaterOrEqual(5, 6, 5)) {
+      currentClient.execute(new QueryPacket("SET SESSION TRANSACTION READ ONLY"), true);
+    }
+
+    if ((oldCtx.getStateFlag() & ConnectionState.STATE_TRANSACTION_ISOLATION) > 0
+        && currentClient.getContext().getTransactionIsolationLevel()
+            != oldCtx.getTransactionIsolationLevel()) {
+      String query = "SET SESSION TRANSACTION ISOLATION LEVEL";
+      switch (oldCtx.getTransactionIsolationLevel()) {
+        case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
+          query += " READ UNCOMMITTED";
+          break;
+        case java.sql.Connection.TRANSACTION_READ_COMMITTED:
+          query += " READ COMMITTED";
+          break;
+        case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
+          query += " REPEATABLE READ";
+          break;
+        case java.sql.Connection.TRANSACTION_SERIALIZABLE:
+          query += " SERIALIZABLE";
+          break;
+      }
+      currentClient
+          .getContext()
+          .setTransactionIsolationLevel(oldCtx.getTransactionIsolationLevel());
+      currentClient.execute(new QueryPacket(query), true);
+    }
+  }
+
+  @Override
+  public List<Completion> execute(ClientMessage message, boolean canRedo) throws SQLException {
+    return execute(
+        message,
+        null,
+        0,
+        0L,
+        ResultSet.CONCUR_READ_ONLY,
+        ResultSet.TYPE_FORWARD_ONLY,
+        false,
+        canRedo);
+  }
+
+  @Override
+  public List<Completion> execute(
+      ClientMessage message, org.mariadb.jdbc.Statement stmt, boolean canRedo) throws SQLException {
+    return execute(
+        message,
+        stmt,
+        0,
+        0L,
+        ResultSet.CONCUR_READ_ONLY,
+        ResultSet.TYPE_FORWARD_ONLY,
+        false,
+        canRedo);
+  }
+
+  @Override
+  public List<Completion> execute(
+      ClientMessage message,
+      Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+
+    try {
+      return currentClient.execute(
+          message,
+          stmt,
+          fetchSize,
+          maxRows,
+          resultSetConcurrency,
+          resultSetType,
+          closeOnCompletion,
+          canRedo);
+    } catch (SQLNonTransientConnectionException e) {
+      HostAddress hostAddress = currentClient.getHostAddress();
+      Client oldClient = reConnect();
+
+      if (message instanceof QueryPacket && ((QueryPacket) message).isCommit()) {
+        throw new SQLTransientConnectionException(
+            String.format(
+                "Driver has reconnect connection after a communications failure with %s during a"
+                    + " COMMIT statement",
+                hostAddress),
+            "25S03");
+      }
+
+      replayIfPossible(oldClient, canRedo);
+
+      if (message instanceof RedoableWithPrepareClientMessage) {
+        ((RedoableWithPrepareClientMessage) message).rePrepare(currentClient);
+      }
+      return currentClient.execute(
+          message,
+          stmt,
+          fetchSize,
+          maxRows,
+          resultSetConcurrency,
+          resultSetType,
+          closeOnCompletion,
+          canRedo);
+    }
+  }
+
+  @Override
+  public List<Completion> executePipeline(
+      ClientMessage[] messages,
+      Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+
+    try {
+      return currentClient.executePipeline(
+          messages,
+          stmt,
+          fetchSize,
+          maxRows,
+          resultSetConcurrency,
+          resultSetType,
+          closeOnCompletion,
+          canRedo);
+    } catch (SQLException e) {
+      if (e instanceof SQLNonTransientConnectionException
+          || (e.getCause() != null && e.getCause() instanceof SQLNonTransientConnectionException)) {
+        Client oldClient = reConnect();
+        replayIfPossible(oldClient, canRedo);
+        Arrays.stream(messages)
+            .filter(RedoableWithPrepareClientMessage.class::isInstance)
+            .map(RedoableWithPrepareClientMessage.class::cast)
+            .forEach(
+                rd -> {
+                  try {
+                    rd.rePrepare(currentClient);
+                  } catch (SQLException sqle) {
+                    // eat
+                  }
+                });
+        return currentClient.executePipeline(
+            messages,
+            stmt,
+            fetchSize,
+            maxRows,
+            resultSetConcurrency,
+            resultSetType,
+            closeOnCompletion,
+            canRedo);
+      }
+      throw e;
+    }
+  }
+
+  @Override
+  public void readStreamingResults(
+      List<Completion> completions,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion)
+      throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+
+    try {
+      currentClient.readStreamingResults(
+          completions, fetchSize, maxRows, resultSetConcurrency, resultSetType, closeOnCompletion);
+    } catch (SQLNonTransientConnectionException e) {
+      try {
+        reConnect();
+      } catch (SQLException e2) {
+        throw getExceptionFactory()
+            .create("Socket error during result streaming", e2.getSQLState(), e2);
+      }
+      throw getExceptionFactory().create("Socket error during result streaming", "HY000", e);
+    }
+  }
+
+  @Override
+  public void closePrepare(Prepare prepare) throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+
+    try {
+      currentClient.closePrepare(prepare);
+    } catch (SQLNonTransientConnectionException e) {
+      reConnect();
+    }
+  }
+
+  @Override
+  public void abort(Executor executor) throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+    currentClient.abort(executor);
+  }
+
+  @Override
+  public void close() throws SQLException {
+    closed = true;
+    currentClient.close();
+  }
+
+  @Override
+  public void setReadOnly(boolean readOnly) throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+  }
+
+  @Override
+  public int getSocketTimeout() {
+    return currentClient.getSocketTimeout();
+  }
+
+  @Override
+  public void setSocketTimeout(int milliseconds) throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+
+    try {
+      currentClient.setSocketTimeout(milliseconds);
+    } catch (SQLNonTransientConnectionException e) {
+      reConnect();
+      currentClient.setSocketTimeout(milliseconds);
+    }
+  }
+
+  @Override
+  public boolean isClosed() {
+    return closed;
+  }
+
+  @Override
+  public Context getContext() {
+    return currentClient.getContext();
+  }
+
+  @Override
+  public ExceptionFactory getExceptionFactory() {
+    return currentClient.getExceptionFactory();
+  }
+
+  @Override
+  public HostAddress getHostAddress() {
+    return currentClient.getHostAddress();
+  }
+
+  public boolean isPrimary() {
+    return true;
+  }
+
+  @Override
+  public void reset() {
+    currentClient.getContext().resetStateFlag();
+    currentClient.getContext().resetPrepareCache();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/MultiPrimaryReplicaClient.java b/src/main/java/org/mariadb/jdbc/client/impl/MultiPrimaryReplicaClient.java
new file mode 100644
index 0000000..8244911
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/MultiPrimaryReplicaClient.java
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.sql.SQLException;
+import java.sql.SQLNonTransientConnectionException;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/**
+ * Handling connection failing automatic reconnection transparently when possible for replication
+ * Topology.
+ *
+ * <p>remark: would have been better using proxy, but for AOT compilation, avoiding to using not
+ * supported proxy class.
+ */
+public class MultiPrimaryReplicaClient extends MultiPrimaryClient {
+  private static final Logger logger = Loggers.getLogger(MultiPrimaryReplicaClient.class);
+
+  /** timeout before retrying to reconnect failing host */
+  protected long waitTimeout;
+
+  private Client replicaClient;
+  private Client primaryClient;
+  private boolean requestReadOnly;
+  private long nextTryReplica = -1;
+  private long nextTryPrimary = -1;
+
+  /**
+   * Constructor
+   *
+   * @param conf configuration
+   * @param lock thread locker
+   * @throws SQLException if any error occurs
+   */
+  public MultiPrimaryReplicaClient(Configuration conf, ReentrantLock lock) throws SQLException {
+    super(conf, lock);
+    primaryClient = currentClient;
+    waitTimeout =
+        Long.parseLong(conf.nonMappedOptions().getProperty("waitReconnectTimeout", "30000"));
+    try {
+      replicaClient = connectHost(true, false);
+    } catch (SQLException e) {
+      replicaClient = null;
+      nextTryReplica = System.currentTimeMillis() + waitTimeout;
+    }
+  }
+
+  private void reconnectIfNeeded() {
+    if (!closed) {
+
+      // try to reconnect primary
+      if (primaryClient == null && nextTryPrimary < System.currentTimeMillis()) {
+        try {
+          primaryClient = connectHost(false, true);
+          nextTryPrimary = -1;
+        } catch (SQLException e) {
+          nextTryPrimary = System.currentTimeMillis() + waitTimeout;
+        }
+      }
+
+      // try to reconnect replica
+      if (replicaClient == null && nextTryReplica < System.currentTimeMillis()) {
+        try {
+          replicaClient = connectHost(true, true);
+          nextTryReplica = -1;
+          if (requestReadOnly) {
+            syncNewState(primaryClient);
+            currentClient = replicaClient;
+          }
+        } catch (SQLException e) {
+          nextTryReplica = System.currentTimeMillis() + waitTimeout;
+        }
+      }
+    }
+  }
+
+  /**
+   * Reconnect connection, trying to continue transparently if possible. Different possible cases :
+   * replica fails, then reconnect to replica or to master if no replica available
+   *
+   * <p>if reconnect succeed on replica / use master, no problem, continuing without interruption //
+   * if reconnect primary, then replay transaction / throw exception if was in transaction.
+   *
+   * @throws SQLException if exception
+   */
+  @Override
+  protected Client reConnect() throws SQLException {
+    denyList.putIfAbsent(
+        currentClient.getHostAddress(), System.currentTimeMillis() + deniedListTimeout);
+    logger.info("Connection error on {}", currentClient.getHostAddress());
+    try {
+      Client oldClient = currentClient;
+      if (oldClient.isPrimary()) {
+        primaryClient = null;
+      } else {
+        replicaClient = null;
+      }
+
+      // remove cached prepare from existing server prepare statement
+      oldClient.getContext().resetPrepareCache();
+
+      try {
+        currentClient = connectHost(requestReadOnly, requestReadOnly);
+        if (requestReadOnly) {
+          nextTryReplica = -1;
+          replicaClient = currentClient;
+        } else {
+          nextTryPrimary = -1;
+          primaryClient = currentClient;
+        }
+
+      } catch (SQLNonTransientConnectionException e) {
+        if (requestReadOnly) {
+          nextTryReplica = System.currentTimeMillis() + waitTimeout;
+          if (primaryClient != null) {
+            // connector will use primary client until some replica is up
+            currentClient = primaryClient;
+          } else {
+            // replication fails, and no primary connection
+            // trying to create new primary connection
+            try {
+              primaryClient = connectHost(false, false);
+              currentClient = primaryClient;
+              nextTryPrimary = -1;
+            } catch (SQLNonTransientConnectionException ee) {
+              closed = true;
+              throw new SQLNonTransientConnectionException(
+                  String.format(
+                      "Driver has failed to reconnect connection after a "
+                          + "communications "
+                          + "failure with %s",
+                      oldClient.getHostAddress()),
+                  "08000");
+            }
+          }
+        } else {
+          throw new SQLNonTransientConnectionException(
+              String.format(
+                  "Driver has failed to reconnect master connection after a "
+                      + "communications "
+                      + "failure with %s",
+                  oldClient.getHostAddress()),
+              "08000");
+        }
+      }
+
+      syncNewState(oldClient);
+
+      // if reconnect succeed on replica / use master, no problem, continuing without interruption
+      // if reconnect primary, then replay transaction / throw exception if was in transaction.
+      return requestReadOnly ? null : oldClient;
+
+    } catch (SQLNonTransientConnectionException sqle) {
+      currentClient = null;
+      closed = true;
+      if (replicaClient != null) {
+        replicaClient.close();
+      }
+      throw sqle;
+    }
+  }
+
+  @Override
+  public List<Completion> execute(
+      ClientMessage message,
+      Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+    reconnectIfNeeded();
+    return super.execute(
+        message,
+        stmt,
+        fetchSize,
+        maxRows,
+        resultSetConcurrency,
+        resultSetType,
+        closeOnCompletion,
+        canRedo);
+  }
+
+  @Override
+  public List<Completion> executePipeline(
+      ClientMessage[] messages,
+      Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+    reconnectIfNeeded();
+    return super.executePipeline(
+        messages,
+        stmt,
+        fetchSize,
+        maxRows,
+        resultSetConcurrency,
+        resultSetType,
+        closeOnCompletion,
+        canRedo);
+  }
+
+  @Override
+  public void readStreamingResults(
+      List<Completion> completions,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion)
+      throws SQLException {
+    reconnectIfNeeded();
+    super.readStreamingResults(
+        completions, fetchSize, maxRows, resultSetConcurrency, resultSetType, closeOnCompletion);
+  }
+
+  @Override
+  public void closePrepare(Prepare prepare) throws SQLException {
+    reconnectIfNeeded();
+    super.closePrepare(prepare);
+  }
+
+  @Override
+  public void abort(Executor executor) throws SQLException {
+    reconnectIfNeeded();
+    super.abort(executor);
+  }
+
+  @Override
+  public void close() throws SQLException {
+    if (!closed) {
+      closed = true;
+      try {
+        if (primaryClient != null) primaryClient.close();
+      } catch (SQLException e) {
+        // eat
+      }
+      try {
+        if (replicaClient != null) replicaClient.close();
+      } catch (SQLException e) {
+        // eat
+      }
+      primaryClient = null;
+      replicaClient = null;
+    }
+  }
+
+  @Override
+  public void setReadOnly(boolean readOnly) throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+    if (readOnly) {
+      // changed ?
+      if (!requestReadOnly) {
+        if (replicaClient != null) {
+          currentClient = replicaClient;
+          syncNewState(primaryClient);
+        } else if (nextTryReplica < System.currentTimeMillis()) {
+          try {
+            replicaClient = connectHost(true, true);
+            currentClient = replicaClient;
+            syncNewState(primaryClient);
+          } catch (SQLException e) {
+            nextTryReplica = System.currentTimeMillis() + waitTimeout;
+          }
+        }
+      }
+    } else {
+      // changed ?
+      if (requestReadOnly) {
+        if (primaryClient != null) {
+          currentClient = primaryClient;
+          syncNewState(replicaClient);
+        } else if (nextTryPrimary < System.currentTimeMillis()) {
+          try {
+            primaryClient = connectHost(false, false);
+            nextTryPrimary = -1;
+            syncNewState(replicaClient);
+          } catch (SQLException e) {
+            nextTryPrimary = System.currentTimeMillis() + waitTimeout;
+            throw new SQLNonTransientConnectionException(
+                "Driver has failed to reconnect a primary connection", "08000");
+          }
+        }
+      }
+    }
+    requestReadOnly = readOnly;
+  }
+
+  @Override
+  public int getSocketTimeout() {
+    reconnectIfNeeded();
+    return super.getSocketTimeout();
+  }
+
+  @Override
+  public void setSocketTimeout(int milliseconds) throws SQLException {
+    reconnectIfNeeded();
+    super.setSocketTimeout(milliseconds);
+  }
+
+  @Override
+  public Context getContext() {
+    reconnectIfNeeded();
+    return super.getContext();
+  }
+
+  @Override
+  public ExceptionFactory getExceptionFactory() {
+    reconnectIfNeeded();
+    return super.getExceptionFactory();
+  }
+
+  @Override
+  public HostAddress getHostAddress() {
+    reconnectIfNeeded();
+    return super.getHostAddress();
+  }
+
+  public boolean isPrimary() {
+    return getHostAddress().primary;
+  }
+
+  @Override
+  public void reset() {
+    if (replicaClient != null) {
+      replicaClient.getContext().resetStateFlag();
+      replicaClient.getContext().resetPrepareCache();
+    }
+    if (primaryClient != null) {
+      primaryClient.getContext().resetStateFlag();
+      primaryClient.getContext().resetPrepareCache();
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/PrepareCache.java b/src/main/java/org/mariadb/jdbc/client/impl/PrepareCache.java
new file mode 100644
index 0000000..1500643
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/PrepareCache.java
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.server.CachedPrepareResultPacket;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+
+/** LRU prepare cache */
+public final class PrepareCache extends LinkedHashMap<String, CachedPrepareResultPacket>
+    implements org.mariadb.jdbc.client.PrepareCache {
+
+  private static final long serialVersionUID = -8922905563713952695L;
+  /** cache maximum size */
+  private final int maxSize;
+  /** client */
+  private final StandardClient con;
+
+  /**
+   * LRU prepare cache constructor
+   *
+   * @param size cache size
+   * @param con client
+   */
+  public PrepareCache(int size, StandardClient con) {
+    super(size, .75f, true);
+    this.maxSize = size;
+    this.con = con;
+  }
+
+  @Override
+  public boolean removeEldestEntry(Map.Entry<String, CachedPrepareResultPacket> eldest) {
+    if (this.size() > maxSize) {
+      eldest.getValue().unCache(con);
+      return true;
+    }
+    return false;
+  }
+
+  public synchronized Prepare get(String key, ServerPreparedStatement preparedStatement) {
+    CachedPrepareResultPacket prepare = super.get(key);
+    if (prepare != null && preparedStatement != null) {
+      prepare.incrementUse(preparedStatement);
+    }
+    return prepare;
+  }
+
+  public synchronized Prepare put(
+      String key, Prepare result, ServerPreparedStatement preparedStatement) {
+    CachedPrepareResultPacket cached = super.get(key);
+
+    // if there is already some cached data, return existing cached data
+    if (cached != null) {
+      cached.incrementUse(preparedStatement);
+      ((CachedPrepareResultPacket) result).unCache(con);
+      return cached;
+    }
+
+    if (((CachedPrepareResultPacket) result).cache()) {
+      ((CachedPrepareResultPacket) result).incrementUse(preparedStatement);
+      super.put(key, (CachedPrepareResultPacket) result);
+    }
+    return null;
+  }
+
+  public CachedPrepareResultPacket get(Object key) {
+    throw new IllegalStateException("not available method");
+  }
+
+  /**
+   * NOT USED
+   *
+   * @param key key
+   * @param result results
+   * @return will throw an exception
+   */
+  @SuppressWarnings("unused")
+  public CachedPrepareResultPacket put(String key, PrepareResultPacket result) {
+    throw new IllegalStateException("not available method");
+  }
+
+  public void reset() {
+    for (CachedPrepareResultPacket prep : values()) {
+      prep.reset();
+    }
+    this.clear();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/ReplayClient.java b/src/main/java/org/mariadb/jdbc/client/impl/ReplayClient.java
new file mode 100644
index 0000000..7278bd8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/ReplayClient.java
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.context.RedoContext;
+import org.mariadb.jdbc.export.MaxAllowedPacketException;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.client.*;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Replay client wrapper */
+public class ReplayClient extends StandardClient {
+  private static final Logger logger = Loggers.getLogger(ReplayClient.class);
+
+  /**
+   * Constructor
+   *
+   * @param conf configuration
+   * @param hostAddress host
+   * @param lock thread lock object
+   * @param skipPostCommands must skip connection post commands
+   * @throws SQLException if connection fails
+   */
+  public ReplayClient(
+      Configuration conf, HostAddress hostAddress, ReentrantLock lock, boolean skipPostCommands)
+      throws SQLException {
+    super(conf, hostAddress, lock, skipPostCommands);
+  }
+
+  @Override
+  public int sendQuery(ClientMessage message) throws SQLException {
+    checkNotClosed();
+    try {
+      if (message instanceof RedoableClientMessage)
+        ((RedoableClientMessage) message).ensureReplayable(context);
+      return message.encode(writer, context);
+    } catch (IOException ioException) {
+      if (ioException instanceof MaxAllowedPacketException) {
+        if (((MaxAllowedPacketException) ioException).isMustReconnect()) {
+          destroySocket();
+          throw exceptionFactory
+              .withSql(message.description())
+              .create(
+                  "Packet too big for current server max_allowed_packet value",
+                  "08000",
+                  ioException);
+        }
+        throw exceptionFactory
+            .withSql(message.description())
+            .create(
+                "Packet too big for current server max_allowed_packet value", "HZ000", ioException);
+      }
+      destroySocket();
+      throw exceptionFactory
+          .withSql(message.description())
+          .create("Socket error", "08000", ioException);
+    }
+  }
+
+  @Override
+  public List<Completion> executePipeline(
+      ClientMessage[] messages,
+      org.mariadb.jdbc.Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+    List<Completion> res =
+        super.executePipeline(
+            messages,
+            stmt,
+            fetchSize,
+            maxRows,
+            resultSetConcurrency,
+            resultSetType,
+            closeOnCompletion,
+            canRedo);
+    ((RedoContext) context).saveRedo(messages);
+    return res;
+  }
+
+  @Override
+  public List<Completion> execute(
+      ClientMessage message,
+      org.mariadb.jdbc.Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+    List<Completion> completions =
+        super.execute(
+            message,
+            stmt,
+            fetchSize,
+            maxRows,
+            resultSetConcurrency,
+            resultSetType,
+            closeOnCompletion,
+            canRedo);
+    ((RedoContext) context).saveRedo(message);
+    return completions;
+  }
+
+  /**
+   * Replay transaction, re-prepare server command if needed
+   *
+   * @param transactionSaver transaction cache
+   * @throws SQLException if any error occurs
+   */
+  public void transactionReplay(TransactionSaver transactionSaver) throws SQLException {
+    RedoableClientMessage[] buffers = transactionSaver.getBuffers();
+    try {
+      // replay all but last
+      Prepare prepare;
+      for (int i = 0; i < transactionSaver.getIdx(); i++) {
+        RedoableClientMessage querySaver = buffers[i];
+        int responseNo;
+        if (querySaver instanceof RedoableWithPrepareClientMessage) {
+          // command is a prepare statement query
+          // redo on new connection need to re-prepare query
+          // and substitute statement id
+          RedoableWithPrepareClientMessage redoable =
+              ((RedoableWithPrepareClientMessage) querySaver);
+          String cmd = redoable.getCommand();
+          prepare = context.getPrepareCache().get(cmd, redoable.prep());
+          if (prepare == null) {
+            PreparePacket preparePacket = new PreparePacket(cmd);
+            sendQuery(preparePacket);
+            prepare = (PrepareResultPacket) readPacket(preparePacket);
+            logger.info("replayed command after failover: " + preparePacket.description());
+          }
+          responseNo = querySaver.reEncode(writer, context, prepare);
+        } else {
+          responseNo = querySaver.reEncode(writer, context, null);
+        }
+        logger.info("replayed command after failover: " + querySaver.description());
+        for (int j = 0; j < responseNo; j++) {
+          readResponse(querySaver);
+        }
+      }
+    } catch (IOException e) {
+      throw context
+          .getExceptionFactory()
+          .create("Socket error during transaction replay", "08000", e);
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java b/src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java
new file mode 100644
index 0000000..d67b79e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/StandardClient.java
@@ -0,0 +1,1016 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.io.*;
+import java.net.Socket;
+import java.net.SocketException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLNonTransientConnectionException;
+import java.time.DateTimeException;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.util.*;
+import java.util.concurrent.Executor;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+import javax.net.ssl.SSLSocket;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.context.BaseContext;
+import org.mariadb.jdbc.client.context.RedoContext;
+import org.mariadb.jdbc.client.result.Result;
+import org.mariadb.jdbc.client.result.StreamingResult;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.socket.impl.*;
+import org.mariadb.jdbc.client.util.MutableByte;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.export.MaxAllowedPacketException;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.client.*;
+import org.mariadb.jdbc.message.server.ErrorPacket;
+import org.mariadb.jdbc.message.server.InitialHandshakePacket;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+import org.mariadb.jdbc.plugin.Credential;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+import org.mariadb.jdbc.util.Security;
+import org.mariadb.jdbc.util.constants.Capabilities;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Connection client */
+public class StandardClient implements Client, AutoCloseable {
+  private static final Logger logger = Loggers.getLogger(StandardClient.class);
+  private final Socket socket;
+  private final MutableByte sequence = new MutableByte();
+  private final MutableByte compressionSequence = new MutableByte();
+  private final ReentrantLock lock;
+  private final Configuration conf;
+  private final HostAddress hostAddress;
+  private boolean closed = false;
+  private Reader reader;
+  private org.mariadb.jdbc.Statement streamStmt = null;
+  private ClientMessage streamMsg = null;
+  private int socketTimeout;
+  private final boolean disablePipeline;
+
+  /** connection context */
+  protected Context context;
+
+  /** connection exception factory */
+  protected final ExceptionFactory exceptionFactory;
+
+  /** packet writer */
+  protected Writer writer;
+
+  /**
+   * Constructor
+   *
+   * @param conf configuration
+   * @param hostAddress host
+   * @param lock thread locker
+   * @param skipPostCommands must connection post command be skipped
+   * @throws SQLException if connection fails
+   */
+  public StandardClient(
+      Configuration conf, HostAddress hostAddress, ReentrantLock lock, boolean skipPostCommands)
+      throws SQLException {
+
+    this.conf = conf;
+    this.lock = lock;
+    this.hostAddress = hostAddress;
+    this.exceptionFactory = new ExceptionFactory(conf, hostAddress);
+    this.disablePipeline = conf.disablePipeline();
+
+    String host = hostAddress != null ? hostAddress.host : null;
+    this.socketTimeout = conf.socketTimeout();
+    this.socket = ConnectionHelper.connectSocket(conf, hostAddress);
+
+    try {
+      // **********************************************************************
+      // creating socket
+      // **********************************************************************
+      OutputStream out = new BufferedOutputStream(socket.getOutputStream(), 16384);
+      InputStream in =
+          conf.useReadAheadInput()
+              ? new ReadAheadBufferedStream(socket.getInputStream())
+              : new BufferedInputStream(socket.getInputStream(), 16384);
+
+      assignStream(out, in, conf, null);
+
+      if (conf.socketTimeout() > 0) setSocketTimeout(conf.socketTimeout());
+
+      // read server handshake
+      ReadableByteBuf buf = reader.readReusablePacket(logger.isTraceEnabled());
+      if (buf.getByte() == -1) {
+        ErrorPacket errorPacket = new ErrorPacket(buf, null);
+        throw this.exceptionFactory.create(
+            errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
+      }
+      final InitialHandshakePacket handshake = InitialHandshakePacket.decode(buf);
+
+      this.exceptionFactory.setThreadId(handshake.getThreadId());
+      long clientCapabilities =
+          ConnectionHelper.initializeClientCapabilities(
+              conf, handshake.getCapabilities(), hostAddress);
+      this.context =
+          conf.transactionReplay()
+              ? new RedoContext(
+                  handshake,
+                  clientCapabilities,
+                  conf,
+                  this.exceptionFactory,
+                  new PrepareCache(conf.prepStmtCacheSize(), this))
+              : new BaseContext(
+                  handshake,
+                  clientCapabilities,
+                  conf,
+                  this.exceptionFactory,
+                  conf.cachePrepStmts() ? new PrepareCache(conf.prepStmtCacheSize(), this) : null);
+
+      this.reader.setServerThreadId(handshake.getThreadId(), hostAddress);
+      this.writer.setServerThreadId(handshake.getThreadId(), hostAddress);
+
+      byte exchangeCharset = ConnectionHelper.decideLanguage(handshake);
+
+      // **********************************************************************
+      // changing to SSL socket if needed
+      // **********************************************************************
+      SSLSocket sslSocket =
+          ConnectionHelper.sslWrapper(
+              hostAddress, socket, clientCapabilities, exchangeCharset, context, writer);
+
+      if (sslSocket != null) {
+        out = new BufferedOutputStream(sslSocket.getOutputStream(), 16384);
+        in =
+            conf.useReadAheadInput()
+                ? new ReadAheadBufferedStream(sslSocket.getInputStream())
+                : new BufferedInputStream(sslSocket.getInputStream(), 16384);
+        assignStream(out, in, conf, handshake.getThreadId());
+      }
+
+      // **********************************************************************
+      // handling authentication
+      // **********************************************************************
+      String authenticationPluginType = handshake.getAuthenticationPluginType();
+      CredentialPlugin credentialPlugin = conf.credentialPlugin();
+      if (credentialPlugin != null && credentialPlugin.defaultAuthenticationPluginType() != null) {
+        authenticationPluginType = credentialPlugin.defaultAuthenticationPluginType();
+      }
+      Credential credential = ConnectionHelper.loadCredential(credentialPlugin, conf, hostAddress);
+
+      new HandshakeResponse(
+              credential,
+              authenticationPluginType,
+              context.getSeed(),
+              conf,
+              host,
+              clientCapabilities,
+              exchangeCharset)
+          .encode(writer, context);
+      writer.flush();
+
+      ConnectionHelper.authenticationHandler(credential, writer, reader, context);
+
+      // **********************************************************************
+      // activate compression if required
+      // **********************************************************************
+      if ((clientCapabilities & Capabilities.COMPRESS) != 0) {
+        assignStream(
+            new CompressOutputStream(out, compressionSequence),
+            new CompressInputStream(in, compressionSequence),
+            conf,
+            handshake.getThreadId());
+      }
+
+      // **********************************************************************
+      // post queries
+      // **********************************************************************
+      if (!skipPostCommands) {
+        postConnectionQueries();
+      }
+
+    } catch (IOException ioException) {
+      destroySocket();
+
+      String errorMsg =
+          String.format(
+              "Could not connect to %s:%s : %s", host, socket.getPort(), ioException.getMessage());
+      if (host == null) {
+        errorMsg = String.format("Could not connect to socket : %s", ioException.getMessage());
+      }
+
+      throw exceptionFactory.create(errorMsg, "08000", ioException);
+    } catch (SQLException sqlException) {
+      destroySocket();
+      throw sqlException;
+    }
+  }
+
+  private void assignStream(OutputStream out, InputStream in, Configuration conf, Long threadId) {
+    this.writer =
+        new PacketWriter(
+            out, conf.maxQuerySizeToLog(), conf.maxAllowedPacket(), sequence, compressionSequence);
+    this.writer.setServerThreadId(threadId, hostAddress);
+
+    this.reader = new PacketReader(in, conf, sequence);
+    this.reader.setServerThreadId(threadId, hostAddress);
+  }
+
+  /** Closing socket in case of Connection error after socket creation. */
+  protected void destroySocket() {
+    closed = true;
+    try {
+      this.reader.close();
+    } catch (IOException ee) {
+      // eat exception
+    }
+    try {
+      this.writer.close();
+    } catch (IOException ee) {
+      // eat exception
+    }
+    try {
+      this.socket.close();
+    } catch (IOException ee) {
+      // eat exception
+    }
+  }
+
+  /**
+   * load server timezone and ensure this corresponds to client timezone
+   *
+   * @throws SQLException if any socket error.
+   */
+  private String handleTimezone() throws SQLException {
+    if (!"disable".equalsIgnoreCase(conf.timezone())) {
+      String timeZone = null;
+      try {
+        Result res =
+            (Result)
+                execute(new QueryPacket("SELECT @@time_zone, @@system_time_zone"), true).get(0);
+        res.next();
+        timeZone = res.getString(1);
+        if ("SYSTEM".equals(timeZone)) {
+          timeZone = res.getString(2);
+        }
+      } catch (SQLException sqle) {
+        Result res =
+            (Result)
+                execute(
+                        new QueryPacket(
+                            "SHOW VARIABLES WHERE Variable_name in ("
+                                + "'system_time_zone',"
+                                + "'time_zone')"),
+                        true)
+                    .get(0);
+        String systemTimeZone = null;
+        while (res.next()) {
+          if ("system_time_zone".equals(res.getString(1))) {
+            systemTimeZone = res.getString(2);
+          } else {
+            timeZone = res.getString(2);
+          }
+        }
+        if ("SYSTEM".equals(timeZone)) {
+          timeZone = systemTimeZone;
+        }
+      }
+      return timeZone;
+    }
+    return null;
+  }
+
+  private void postConnectionQueries() throws SQLException {
+    List<String> commands = new ArrayList<>();
+
+    List<String> galeraAllowedStates =
+        conf.galeraAllowedState() == null
+            ? Collections.emptyList()
+            : Arrays.asList(conf.galeraAllowedState().split(","));
+
+    if (hostAddress != null
+        && Boolean.TRUE.equals(hostAddress.primary)
+        && !galeraAllowedStates.isEmpty()) {
+      commands.add("show status like 'wsrep_local_state'");
+    }
+
+    String serverTz = conf.timezone() != null ? handleTimezone() : null;
+    String sessionVariableQuery = createSessionVariableQuery(serverTz);
+    if (sessionVariableQuery != null) commands.add(sessionVariableQuery);
+
+    if (hostAddress != null
+        && !hostAddress.primary
+        && context.getVersion().versionGreaterOrEqual(5, 6, 5)) {
+      commands.add("SET SESSION TRANSACTION READ ONLY");
+    }
+
+    if (conf.database() != null
+        && conf.createDatabaseIfNotExist()
+        && (hostAddress == null || hostAddress.primary)) {
+      String escapedDb = conf.database().replace("`", "``");
+      commands.add(String.format("CREATE DATABASE IF NOT EXISTS `%s`", escapedDb));
+      commands.add(String.format("USE `%s`", escapedDb));
+    }
+
+    if (conf.initSql() != null) {
+      commands.add(conf.initSql());
+    }
+
+    if (conf.nonMappedOptions().containsKey("initSql")) {
+      String[] initialCommands = conf.nonMappedOptions().get("initSql").toString().split(";");
+      for (String cmd : initialCommands) {
+        commands.add(cmd);
+      }
+    }
+
+    if (!commands.isEmpty()) {
+      try {
+        List<Completion> res;
+        ClientMessage[] msgs = new ClientMessage[commands.size()];
+        for (int i = 0; i < commands.size(); i++) {
+          msgs[i] = new QueryPacket(commands.get(i));
+        }
+        res =
+            executePipeline(
+                msgs,
+                null,
+                0,
+                0L,
+                ResultSet.CONCUR_READ_ONLY,
+                ResultSet.TYPE_FORWARD_ONLY,
+                false,
+                true);
+
+        if (hostAddress != null
+            && Boolean.TRUE.equals(hostAddress.primary)
+            && !galeraAllowedStates.isEmpty()) {
+          ResultSet rs = (ResultSet) res.get(0);
+          if (rs.next()) {
+            if (!galeraAllowedStates.contains(rs.getString(2))) {
+              throw exceptionFactory.create(
+                  String.format("fail to validate Galera state (State is %s)", rs.getString(2)));
+            }
+          } else {
+            throw exceptionFactory.create(
+                "fail to validate Galera state (unknown 'wsrep_local_state' state)");
+          }
+          res.remove(0);
+        }
+
+      } catch (SQLException sqlException) {
+
+        if (conf.timezone() != null && !"disable".equalsIgnoreCase(conf.timezone())) {
+          // timezone is not valid
+          throw exceptionFactory.create(
+              String.format(
+                  "Setting configured timezone '%s' fail on server.\n"
+                      + "Look at https://mariadb.com/kb/en/mysql_tzinfo_to_sql/ to load tz data on"
+                      + " server, or set timezone=disable to disable setting client timezone.",
+                  conf.timezone()),
+              "HY000",
+              sqlException);
+        }
+        throw exceptionFactory.create("Initialization command fail", "08000", sqlException);
+      }
+    }
+  }
+
+  /**
+   * Create session variable if configuration requires additional commands.
+   *
+   * @param serverTz server timezone
+   * @return sql setting session command
+   */
+  public String createSessionVariableQuery(String serverTz) {
+    // In JDBC, connection must start in autocommit mode
+    // [CONJ-269] we cannot rely on serverStatus & ServerStatus.AUTOCOMMIT before this command to
+    // avoid this command.
+    // if autocommit=0 is set on server configuration, DB always send Autocommit on serverStatus
+    // flag
+    // after setting autocommit, we can rely on serverStatus value
+    List<String> sessionCommands = new ArrayList<>();
+    if (conf.autocommit() != null) {
+      sessionCommands.add("autocommit=" + (conf.autocommit() ? "1" : "0"));
+    }
+
+    // add configured session variable if configured
+    if (conf.sessionVariables() != null) {
+      sessionCommands.add(Security.parseSessionVariables(conf.sessionVariables()));
+    }
+
+    // force client timezone to connection to ensure result of now(), ...
+    if (conf.timezone() != null && !"disable".equalsIgnoreCase(conf.timezone())) {
+      boolean mustSetTimezone = true;
+      TimeZone connectionTz =
+          "auto".equalsIgnoreCase(conf.timezone())
+              ? TimeZone.getDefault()
+              : TimeZone.getTimeZone(ZoneId.of(conf.timezone()).normalized());
+      ZoneId clientZoneId = connectionTz.toZoneId();
+
+      // try to avoid timezone consideration if server use the same one
+      try {
+        ZoneId serverZoneId = ZoneId.of(serverTz);
+        if (serverZoneId.normalized().equals(clientZoneId)
+            || ZoneId.of(serverTz, ZoneId.SHORT_IDS).equals(clientZoneId)) {
+          mustSetTimezone = false;
+        }
+      } catch (DateTimeException e) {
+        // eat
+      }
+
+      if (mustSetTimezone) {
+        if (clientZoneId.getRules().isFixedOffset()) {
+          ZoneOffset zoneOffset = clientZoneId.getRules().getOffset(Instant.now());
+          if (zoneOffset.getTotalSeconds() == 0) {
+            // specific for UTC timezone, server permitting only SYSTEM/UTC offset or named time
+            // zone
+            // not 'UTC'/'Z'
+            sessionCommands.add("time_zone='+00:00'");
+          } else {
+            sessionCommands.add("time_zone='" + zoneOffset.getId() + "'");
+          }
+        } else {
+          sessionCommands.add("time_zone='" + clientZoneId.normalized() + "'");
+        }
+      }
+    }
+
+    if (conf.transactionIsolation() != null) {
+      int major = context.getVersion().getMajorVersion();
+      if (!context.getVersion().isMariaDBServer()
+          && ((major >= 8 && context.getVersion().versionGreaterOrEqual(8, 0, 3))
+              || (major < 8 && context.getVersion().versionGreaterOrEqual(5, 7, 20)))) {
+        sessionCommands.add(
+            "transaction_isolation='" + conf.transactionIsolation().getValue() + "'");
+      } else {
+        sessionCommands.add("tx_isolation='" + conf.transactionIsolation().getValue() + "'");
+      }
+    }
+
+    if (!sessionCommands.isEmpty()) {
+      return "set " + sessionCommands.stream().collect(Collectors.joining(","));
+    }
+    return null;
+  }
+
+  public void setReadOnly(boolean readOnly) throws SQLException {
+    if (closed) {
+      throw new SQLNonTransientConnectionException("Connection is closed", "08000", 1220);
+    }
+  }
+
+  /**
+   * Send client message to server
+   *
+   * @param message client message
+   * @return number of command send
+   * @throws SQLException if socket error occurs
+   */
+  public int sendQuery(ClientMessage message) throws SQLException {
+    checkNotClosed();
+    try {
+      if (logger.isDebugEnabled() && message.description() != null) {
+        logger.debug("execute query: {}", message.description());
+      }
+      return message.encode(writer, context);
+    } catch (IOException ioException) {
+      if (ioException instanceof MaxAllowedPacketException) {
+        if (((MaxAllowedPacketException) ioException).isMustReconnect()) {
+          destroySocket();
+          throw exceptionFactory
+              .withSql(message.description())
+              .create(
+                  "Packet too big for current server max_allowed_packet value",
+                  "08000",
+                  ioException);
+        }
+        throw exceptionFactory
+            .withSql(message.description())
+            .create(
+                "Packet too big for current server max_allowed_packet value", "HZ000", ioException);
+      }
+      destroySocket();
+      throw exceptionFactory
+          .withSql(message.description())
+          .create("Socket error", "08000", ioException);
+    }
+  }
+
+  public List<Completion> execute(ClientMessage message, boolean canRedo) throws SQLException {
+    return execute(
+        message,
+        null,
+        0,
+        0L,
+        ResultSet.CONCUR_READ_ONLY,
+        ResultSet.TYPE_FORWARD_ONLY,
+        false,
+        canRedo);
+  }
+
+  public List<Completion> execute(
+      ClientMessage message, org.mariadb.jdbc.Statement stmt, boolean canRedo) throws SQLException {
+    return execute(
+        message,
+        stmt,
+        0,
+        0L,
+        ResultSet.CONCUR_READ_ONLY,
+        ResultSet.TYPE_FORWARD_ONLY,
+        false,
+        canRedo);
+  }
+
+  public List<Completion> executePipeline(
+      ClientMessage[] messages,
+      org.mariadb.jdbc.Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+    List<Completion> results = new ArrayList<>();
+
+    int readCounter = 0;
+    int[] responseMsg = new int[messages.length];
+    try {
+      if (disablePipeline) {
+        for (readCounter = 0; readCounter < messages.length; readCounter++) {
+          results.addAll(
+              execute(
+                  messages[readCounter],
+                  stmt,
+                  fetchSize,
+                  maxRows,
+                  resultSetConcurrency,
+                  resultSetType,
+                  closeOnCompletion,
+                  canRedo));
+        }
+      } else {
+        for (int i = 0; i < messages.length; i++) {
+          responseMsg[i] = sendQuery(messages[i]);
+        }
+        while (readCounter < messages.length) {
+          readCounter++;
+          for (int j = 0; j < responseMsg[readCounter - 1]; j++) {
+            results.addAll(
+                readResponse(
+                    stmt,
+                    messages[readCounter - 1],
+                    fetchSize,
+                    maxRows,
+                    resultSetConcurrency,
+                    resultSetType,
+                    closeOnCompletion));
+          }
+        }
+      }
+      return results;
+    } catch (SQLException sqlException) {
+      if (!closed) {
+        // read remaining results
+        for (int i = readCounter; i < messages.length; i++) {
+          for (int j = 0; j < responseMsg[i]; j++) {
+            try {
+              results.addAll(
+                  readResponse(
+                      stmt,
+                      messages[i],
+                      fetchSize,
+                      maxRows,
+                      resultSetConcurrency,
+                      resultSetType,
+                      closeOnCompletion));
+            } catch (SQLException e) {
+              // eat
+            }
+          }
+        }
+
+        // prepare associated to PrepareStatement need to be uncached
+        for (Completion result : results) {
+          if (result instanceof PrepareResultPacket && stmt instanceof ServerPreparedStatement) {
+            try {
+              ((PrepareResultPacket) result).decrementUse(this, (ServerPreparedStatement) stmt);
+            } catch (SQLException e) {
+              // eat
+            }
+          }
+        }
+      }
+
+      int batchUpdateLength = 0;
+      for (ClientMessage message : messages) {
+        batchUpdateLength += message.batchUpdateLength();
+      }
+      throw exceptionFactory.createBatchUpdate(
+          results, batchUpdateLength, responseMsg, sqlException);
+    }
+  }
+
+  public List<Completion> execute(
+      ClientMessage message,
+      org.mariadb.jdbc.Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean canRedo)
+      throws SQLException {
+    int nbResp = sendQuery(message);
+    if (nbResp == 1) {
+      return readResponse(
+          stmt,
+          message,
+          fetchSize,
+          maxRows,
+          resultSetConcurrency,
+          resultSetType,
+          closeOnCompletion);
+    } else {
+      if (streamStmt != null) {
+        streamStmt.fetchRemaining();
+        streamStmt = null;
+      }
+      List<Completion> completions = new ArrayList<>();
+      try {
+        while (nbResp-- > 0) {
+          readResults(
+              stmt,
+              message,
+              completions,
+              fetchSize,
+              maxRows,
+              resultSetConcurrency,
+              resultSetType,
+              closeOnCompletion);
+        }
+        return completions;
+      } catch (SQLException e) {
+        while (nbResp-- > 0) {
+          try {
+            readResults(
+                stmt,
+                message,
+                completions,
+                fetchSize,
+                maxRows,
+                resultSetConcurrency,
+                resultSetType,
+                closeOnCompletion);
+          } catch (SQLException ee) {
+            // eat
+          }
+        }
+        throw e;
+      }
+    }
+  }
+
+  /**
+   * Read server responses for a client message
+   *
+   * @param stmt statement that issue the message
+   * @param message client message sent
+   * @param fetchSize fetch size
+   * @param maxRows maximum number of rows
+   * @param resultSetConcurrency concurrency
+   * @param resultSetType result-set type
+   * @param closeOnCompletion close statement on resultset completion
+   * @return list of result
+   * @throws SQLException if any error occurs
+   */
+  public List<Completion> readResponse(
+      org.mariadb.jdbc.Statement stmt,
+      ClientMessage message,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion)
+      throws SQLException {
+    checkNotClosed();
+    if (streamStmt != null) {
+      streamStmt.fetchRemaining();
+      streamStmt = null;
+    }
+    List<Completion> completions = new ArrayList<>();
+    readResults(
+        stmt,
+        message,
+        completions,
+        fetchSize,
+        maxRows,
+        resultSetConcurrency,
+        resultSetType,
+        closeOnCompletion);
+    return completions;
+  }
+
+  /**
+   * Read server response
+   *
+   * @param message client message that was sent
+   * @throws SQLException if any error occurs
+   */
+  public void readResponse(ClientMessage message) throws SQLException {
+    checkNotClosed();
+    if (streamStmt != null) {
+      streamStmt.fetchRemaining();
+      streamStmt = null;
+    }
+    List<Completion> completions = new ArrayList<>();
+    readResults(
+        null,
+        message,
+        completions,
+        0,
+        0L,
+        ResultSet.CONCUR_READ_ONLY,
+        ResultSet.TYPE_FORWARD_ONLY,
+        false);
+  }
+
+  public void closePrepare(Prepare prepare) throws SQLException {
+    checkNotClosed();
+    try {
+      new ClosePreparePacket(prepare.getStatementId()).encode(writer, context);
+    } catch (IOException ioException) {
+      destroySocket();
+      throw exceptionFactory.create(
+          "Socket error during post connection queries: " + ioException.getMessage(),
+          "08000",
+          ioException);
+    }
+  }
+
+  public void readStreamingResults(
+      List<Completion> completions,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion)
+      throws SQLException {
+    if (streamStmt != null) {
+      readResults(
+          streamStmt,
+          streamMsg,
+          completions,
+          fetchSize,
+          maxRows,
+          resultSetConcurrency,
+          resultSetType,
+          closeOnCompletion);
+    }
+  }
+
+  private void readResults(
+      org.mariadb.jdbc.Statement stmt,
+      ClientMessage message,
+      List<Completion> completions,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion)
+      throws SQLException {
+    completions.add(
+        readPacket(
+            stmt,
+            message,
+            fetchSize,
+            maxRows,
+            resultSetConcurrency,
+            resultSetType,
+            closeOnCompletion));
+
+    while ((context.getServerStatus() & ServerStatus.MORE_RESULTS_EXISTS) > 0) {
+      completions.add(
+          readPacket(
+              stmt,
+              message,
+              fetchSize,
+              maxRows,
+              resultSetConcurrency,
+              resultSetType,
+              closeOnCompletion));
+    }
+  }
+
+  /**
+   * Read a MySQL packet from socket
+   *
+   * @param message client message issuing the result
+   * @return a mysql result
+   * @throws SQLException if any error occurs
+   */
+  public Completion readPacket(ClientMessage message) throws SQLException {
+    return readPacket(
+        null, message, 0, 0L, ResultSet.CONCUR_READ_ONLY, ResultSet.TYPE_FORWARD_ONLY, false);
+  }
+
+  /**
+   * Read server response packet.
+   *
+   * @see <a href="https://mariadb.com/kb/en/mariadb/4-server-response-packets/">server response
+   *     packets</a>
+   * @param stmt current statement (null if internal)
+   * @param message current message
+   * @param fetchSize default fetch size
+   * @param maxRows maximum row number
+   * @param resultSetConcurrency concurrency
+   * @param resultSetType type
+   * @param closeOnCompletion must resultset close statement on completion
+   * @return Completion
+   * @throws SQLException if any exception
+   */
+  public Completion readPacket(
+      org.mariadb.jdbc.Statement stmt,
+      ClientMessage message,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion)
+      throws SQLException {
+    try {
+      boolean traceEnable = logger.isTraceEnabled();
+      Completion completion =
+          message.readPacket(
+              stmt,
+              fetchSize,
+              maxRows,
+              resultSetConcurrency,
+              resultSetType,
+              closeOnCompletion,
+              reader,
+              writer,
+              context,
+              exceptionFactory,
+              lock,
+              traceEnable,
+              message);
+      if (completion instanceof StreamingResult && !((StreamingResult) completion).loaded()) {
+        streamStmt = stmt;
+        streamMsg = message;
+      }
+      return completion;
+    } catch (IOException ioException) {
+      destroySocket();
+      throw exceptionFactory
+          .withSql(message.description())
+          .create("Socket error", "08000", ioException);
+    }
+  }
+
+  /**
+   * Throw an exception if client is closed
+   *
+   * @throws SQLException if closed
+   */
+  protected void checkNotClosed() throws SQLException {
+    if (closed) {
+      throw exceptionFactory.create("Connection is closed", "08000", 1220);
+    }
+  }
+
+  private void closeSocket() {
+    try {
+      try {
+        long maxCurrentMillis = System.currentTimeMillis() + 10;
+        socket.shutdownOutput();
+        socket.setSoTimeout(3);
+        InputStream is = socket.getInputStream();
+        //noinspection StatementWithEmptyBody
+        while (is.read() != -1 && System.currentTimeMillis() < maxCurrentMillis) {
+          // read byte
+        }
+      } catch (Throwable t) {
+        // eat exception
+      }
+      writer.close();
+      reader.close();
+    } catch (IOException e) {
+      // eat
+    } finally {
+      try {
+        socket.close();
+      } catch (IOException e) {
+        // socket closed, if any error, so not throwing error
+      }
+    }
+  }
+
+  public boolean isClosed() {
+    return closed;
+  }
+
+  public Context getContext() {
+    return context;
+  }
+
+  public void abort(Executor executor) throws SQLException {
+
+    if (executor == null) {
+      throw exceptionFactory.create("Cannot abort the connection: null executor passed");
+    }
+
+    //    fireConnectionClosed(new ConnectionEvent(this));
+    boolean lockStatus = lock.tryLock();
+
+    if (!this.closed) {
+      this.closed = true;
+      logger.debug("aborting connection {}", context.getThreadId());
+      if (!lockStatus) {
+        // lock not available : query is running
+        // force end by executing an KILL connection
+        try (StandardClient cli =
+            new StandardClient(conf, hostAddress, new ReentrantLock(), true)) {
+          cli.execute(new QueryPacket("KILL " + context.getThreadId()), false);
+        } catch (SQLException e) {
+          // eat
+        }
+      } else {
+        try {
+          QuitPacket.INSTANCE.encode(writer, context);
+        } catch (IOException e) {
+          // eat
+        }
+      }
+      if (streamStmt != null) {
+        streamStmt.abort();
+      }
+      closeSocket();
+    }
+
+    if (lockStatus) {
+      lock.unlock();
+    }
+  }
+
+  public int getSocketTimeout() {
+    return this.socketTimeout;
+  }
+
+  public void setSocketTimeout(int milliseconds) throws SQLException {
+    try {
+      socketTimeout = milliseconds;
+      socket.setSoTimeout(milliseconds);
+    } catch (SocketException se) {
+      throw exceptionFactory.create("Cannot set the network timeout", "42000", se);
+    }
+  }
+
+  public void close() {
+    boolean locked = lock.tryLock();
+
+    if (!this.closed) {
+      this.closed = true;
+      try {
+        QuitPacket.INSTANCE.encode(writer, context);
+      } catch (IOException e) {
+        // eat
+      }
+      closeSocket();
+    }
+
+    if (locked) {
+      lock.unlock();
+    }
+  }
+
+  public boolean isPrimary() {
+    return hostAddress.primary;
+  }
+
+  public ExceptionFactory getExceptionFactory() {
+    return exceptionFactory;
+  }
+
+  public HostAddress getHostAddress() {
+    return hostAddress;
+  }
+
+  public void reset() {
+    context.resetStateFlag();
+    context.resetPrepareCache();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/StandardReadableByteBuf.java b/src/main/java/org/mariadb/jdbc/client/impl/StandardReadableByteBuf.java
new file mode 100644
index 0000000..62746b5
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/StandardReadableByteBuf.java
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.nio.charset.StandardCharsets;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+
+/** Packet buffer */
+public final class StandardReadableByteBuf implements ReadableByteBuf {
+  /** row data limit */
+  private int limit;
+
+  /** buffer */
+  public byte[] buf;
+
+  /** current position reading buffer */
+  public int pos;
+
+  /**
+   * Packet buffer constructor
+   *
+   * @param buf buffer
+   * @param limit buffer limit
+   */
+  public StandardReadableByteBuf(byte[] buf, int limit) {
+    this.pos = 0;
+    this.buf = buf;
+    this.limit = limit;
+  }
+
+  /**
+   * Packet buffer constructor, limit being the buffer length
+   *
+   * @param buf buffer
+   */
+  public StandardReadableByteBuf(byte[] buf) {
+    this.pos = 0;
+    this.buf = buf;
+    this.limit = buf.length;
+  }
+
+  public int readableBytes() {
+    return limit - pos;
+  }
+
+  public int pos() {
+    return pos;
+  }
+
+  public byte[] buf() {
+    return buf;
+  }
+
+  public void buf(byte[] buf, int limit, int pos) {
+    this.buf = buf;
+    this.limit = limit;
+    this.pos = pos;
+  }
+
+  public void pos(int pos) {
+    this.pos = pos;
+  }
+
+  public void skip() {
+    pos++;
+  }
+
+  public void skip(int length) {
+    pos += length;
+  }
+
+  public void skipLengthEncoded() {
+    byte len = buf[pos++];
+    switch (len) {
+      case (byte) 251:
+        return;
+      case (byte) 252:
+        skip(readUnsignedShort());
+        return;
+      case (byte) 253:
+        skip(readUnsignedMedium());
+        return;
+      case (byte) 254:
+        skip((int) (4 + readUnsignedInt()));
+        return;
+      default:
+        pos += len & 0xff;
+        return;
+    }
+  }
+
+  public MariaDbBlob readBlob(int length) {
+    pos += length;
+    return MariaDbBlob.safeMariaDbBlob(buf, pos - length, length);
+  }
+
+  public long atoll(int length) {
+    boolean negate = false;
+    int idx = 0;
+    long result = 0;
+
+    if (length > 0 && buf[pos] == 45) { // minus sign
+      negate = true;
+      pos++;
+      idx++;
+    }
+
+    while (idx++ < length) {
+      result = result * 10 + buf[pos++] - 48;
+    }
+
+    return (negate) ? -1 * result : result;
+  }
+
+  public long atoull(int length) {
+    long result = 0;
+    for (int idx = 0; idx < length; idx++) {
+      result = result * 10 + buf[pos++] - 48;
+    }
+    return result;
+  }
+
+  public byte getByte() {
+    return buf[pos];
+  }
+
+  public byte getByte(int index) {
+    return buf[index];
+  }
+
+  public short getUnsignedByte() {
+    return (short) (buf[pos] & 0xff);
+  }
+
+  public long readLongLengthEncodedNotNull() {
+    int type = (buf[pos++] & 0xff);
+    if (type < 251) return type;
+    switch (type) {
+      case 252: // 0xfc
+        return readUnsignedShort();
+      case 253: // 0xfd
+        return readUnsignedMedium();
+      default: // 0xfe
+        return readLong();
+    }
+  }
+
+  public int readIntLengthEncodedNotNull() {
+    int type = (buf[pos++] & 0xff);
+    if (type < 251) return type;
+    switch (type) {
+      case 252:
+        return readUnsignedShort();
+      case 253:
+        return readUnsignedMedium();
+      case 254:
+        return (int) readLong();
+      default:
+        return type;
+    }
+  }
+
+  /**
+   * Identifier can have a max length of 256 (alias) So no need to check whole length encoding.
+   *
+   * @return current pos
+   */
+  public int skipIdentifier() {
+    int len = readIntLengthEncodedNotNull();
+    pos += len;
+    return pos;
+  }
+
+  public Integer readLength() {
+    int type = readUnsignedByte();
+    switch (type) {
+      case 251:
+        return null;
+      case 252:
+        return readUnsignedShort();
+      case 253:
+        return readUnsignedMedium();
+      case 254:
+        return (int) readLong();
+      default:
+        return type;
+    }
+  }
+
+  public byte readByte() {
+    return buf[pos++];
+  }
+
+  public short readUnsignedByte() {
+    return (short) (buf[pos++] & 0xff);
+  }
+
+  public short readShort() {
+    return (short) ((buf[pos++] & 0xff) + (buf[pos++] << 8));
+  }
+
+  public int readUnsignedShort() {
+    return ((buf[pos++] & 0xff) + (buf[pos++] << 8)) & 0xffff;
+  }
+
+  public int readMedium() {
+    int value = readUnsignedMedium();
+    if ((value & 0x800000) != 0) {
+      value |= 0xff000000;
+    }
+    return value;
+  }
+
+  public int readUnsignedMedium() {
+    return ((buf[pos++] & 0xff) + ((buf[pos++] & 0xff) << 8) + ((buf[pos++] & 0xff) << 16));
+  }
+
+  public int readInt() {
+    return ((buf[pos++] & 0xff)
+        + ((buf[pos++] & 0xff) << 8)
+        + ((buf[pos++] & 0xff) << 16)
+        + ((buf[pos++] & 0xff) << 24));
+  }
+
+  public int readIntBE() {
+    return (((buf[pos++] & 0xff) << 24)
+        + ((buf[pos++] & 0xff) << 16)
+        + ((buf[pos++] & 0xff) << 8)
+        + (buf[pos++] & 0xff));
+  }
+
+  public long readUnsignedInt() {
+    return ((buf[pos++] & 0xff)
+            + ((buf[pos++] & 0xff) << 8)
+            + ((buf[pos++] & 0xff) << 16)
+            + ((long) (buf[pos++] & 0xff) << 24))
+        & 0xffffffffL;
+  }
+
+  public long readLong() {
+    return ((buf[pos++] & 0xffL)
+        + ((buf[pos++] & 0xffL) << 8)
+        + ((buf[pos++] & 0xffL) << 16)
+        + ((buf[pos++] & 0xffL) << 24)
+        + ((buf[pos++] & 0xffL) << 32)
+        + ((buf[pos++] & 0xffL) << 40)
+        + ((buf[pos++] & 0xffL) << 48)
+        + ((buf[pos++] & 0xffL) << 56));
+  }
+
+  public long readLongBE() {
+    return (((buf[pos++] & 0xffL) << 56)
+        + ((buf[pos++] & 0xffL) << 48)
+        + ((buf[pos++] & 0xffL) << 40)
+        + ((buf[pos++] & 0xffL) << 32)
+        + ((buf[pos++] & 0xffL) << 24)
+        + ((buf[pos++] & 0xffL) << 16)
+        + ((buf[pos++] & 0xffL) << 8)
+        + (buf[pos++] & 0xffL));
+  }
+
+  public void readBytes(byte[] dst) {
+    System.arraycopy(buf, pos, dst, 0, dst.length);
+    pos += dst.length;
+  }
+
+  public byte[] readBytesNullEnd() {
+    int initialPosition = pos;
+    int cnt = 0;
+    while (readableBytes() > 0 && (buf[pos++] != 0)) {
+      cnt++;
+    }
+    byte[] dst = new byte[cnt];
+    System.arraycopy(buf, initialPosition, dst, 0, dst.length);
+    return dst;
+  }
+
+  public StandardReadableByteBuf readLengthBuffer() {
+    int len = this.readIntLengthEncodedNotNull();
+    byte[] tmp = new byte[len];
+    readBytes(tmp);
+    return new StandardReadableByteBuf(tmp, len);
+  }
+
+  public String readString(int length) {
+    pos += length;
+    return new String(buf, pos - length, length, StandardCharsets.UTF_8);
+  }
+
+  public String readAscii(int length) {
+    pos += length;
+    return new String(buf, pos - length, length, StandardCharsets.US_ASCII);
+  }
+
+  public String readStringNullEnd() {
+    int initialPosition = pos;
+    int cnt = 0;
+    while (readableBytes() > 0 && (buf[pos++] != 0)) {
+      cnt++;
+    }
+    return new String(buf, initialPosition, cnt, StandardCharsets.UTF_8);
+  }
+
+  public String readStringEof() {
+    int initialPosition = pos;
+    pos = limit;
+    return new String(buf, initialPosition, pos - initialPosition, StandardCharsets.UTF_8);
+  }
+
+  public float readFloat() {
+    return Float.intBitsToFloat(readInt());
+  }
+
+  public double readDouble() {
+    return Double.longBitsToDouble(readLong());
+  }
+
+  public double readDoubleBE() {
+    return Double.longBitsToDouble(readLongBE());
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/impl/TransactionSaver.java b/src/main/java/org/mariadb/jdbc/client/impl/TransactionSaver.java
new file mode 100644
index 0000000..a9c8f54
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/impl/TransactionSaver.java
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.impl;
+
+import java.util.Arrays;
+import org.mariadb.jdbc.message.client.RedoableClientMessage;
+
+/**
+ * Transaction cache Huge command are not cached, cache is limited to configuration
+ * transactionReplaySize commands
+ */
+public class TransactionSaver {
+  private final RedoableClientMessage[] buffers;
+  private int idx = 0;
+  private boolean dirty = false;
+
+  /**
+   * Constructor
+   *
+   * @param transactionReplaySize maximum number of command cached
+   */
+  public TransactionSaver(int transactionReplaySize) {
+    buffers = new RedoableClientMessage[transactionReplaySize];
+  }
+
+  /**
+   * Add a command to cache.
+   *
+   * @param clientMessage client message
+   */
+  public void add(RedoableClientMessage clientMessage) {
+    if (idx < buffers.length) {
+      buffers[idx++] = clientMessage;
+    } else {
+      dirty = true;
+    }
+  }
+
+  /** Transaction finished, clearing cache */
+  public void clear() {
+    Arrays.fill(buffers, null);
+    dirty = false;
+    idx = 0;
+  }
+
+  /**
+   * Current transaction cache length
+   *
+   * @return cache length
+   */
+  public int getIdx() {
+    return idx;
+  }
+
+  /**
+   * Is cache not valid (some commands have not been cached)
+   *
+   * @return is dirty
+   */
+  public boolean isDirty() {
+    return dirty;
+  }
+
+  /**
+   * cache buffer
+   *
+   * @return cached messages
+   */
+  public RedoableClientMessage[] getBuffers() {
+    return buffers;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/CompleteResult.java b/src/main/java/org/mariadb/jdbc/client/result/CompleteResult.java
new file mode 100644
index 0000000..e407ed5
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/CompleteResult.java
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.result;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.socket.Reader;
+
+/** Result-set that will retrieve all rows immediately before returning the result-set. */
+public class CompleteResult extends Result {
+
+  /** before first row position = initial position */
+  protected static final int BEFORE_FIRST_POS = -1;
+
+  /**
+   * Constructor from exchanges
+   *
+   * @param stmt current statement
+   * @param binaryProtocol does exchanges uses binary protocol
+   * @param maxRows maximum number of rows
+   * @param metadataList metadata
+   * @param reader packet reader
+   * @param context connection context
+   * @param resultSetType result set type
+   * @param closeOnCompletion close statement on completion
+   * @param traceEnable network trace exchange possible
+   * @throws IOException if Socket error occurs
+   * @throws SQLException for all other kind of errors
+   */
+  public CompleteResult(
+      Statement stmt,
+      boolean binaryProtocol,
+      long maxRows,
+      ColumnDecoder[] metadataList,
+      Reader reader,
+      Context context,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean traceEnable)
+      throws IOException, SQLException {
+
+    super(
+        stmt,
+        binaryProtocol,
+        maxRows,
+        metadataList,
+        reader,
+        context,
+        resultSetType,
+        closeOnCompletion,
+        traceEnable);
+    this.data = new byte[10][];
+    if (maxRows > 0) {
+      while (readNext() && dataSize < maxRows) {}
+      if (!loaded) skipRemaining();
+    } else {
+      while (readNext()) {}
+    }
+    loaded = true;
+  }
+
+  /**
+   * Specific constructor for internal build result-set, empty resultset, or generated key
+   * result-set.
+   *
+   * @param metadataList metadata
+   * @param data result-set data
+   * @param context connection context
+   */
+  public CompleteResult(ColumnDecoder[] metadataList, byte[][] data, Context context) {
+    super(metadataList, data, context);
+  }
+
+  /**
+   * Specific constructor for generating generated key result-set.
+   *
+   * @param columnName column key
+   * @param columnType column key type
+   * @param data values
+   * @param context connection context
+   * @param flags column flags
+   * @return result-set
+   */
+  public static ResultSet createResultSet(
+      String columnName, DataType columnType, String[][] data, Context context, int flags) {
+    return createResultSet(
+        new String[] {columnName}, new DataType[] {columnType}, data, context, flags);
+  }
+
+  /**
+   * Create a result set from given data. Useful for creating "fake" resultSets for
+   * DatabaseMetaData, (one example is MariaDbDatabaseMetaData.getTypeInfo())
+   *
+   * @param columnNames - string array of column names
+   * @param columnTypes - column types
+   * @param data - each element of this array represents a complete row in the ResultSet. Each value
+   *     is given in its string representation, as in MariaDB text protocol, except boolean (BIT(1))
+   *     values that are represented as "1" or "0" strings
+   * @param context connection context
+   * @param flags column flags
+   * @return resultset
+   */
+  public static ResultSet createResultSet(
+      String[] columnNames, DataType[] columnTypes, String[][] data, Context context, int flags) {
+
+    int columnNameLength = columnNames.length;
+    ColumnDecoder[] columns = new ColumnDecoder[columnNameLength];
+
+    for (int i = 0; i < columnNameLength; i++) {
+      columns[i] = ColumnDecoder.create(columnNames[i], columnTypes[i], flags);
+    }
+
+    List<byte[]> rows = new ArrayList<>();
+    for (String[] rowData : data) {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+      for (String rowDatum : rowData) {
+
+        if (rowDatum != null) {
+          byte[] bb = rowDatum.getBytes();
+          int len = bb.length;
+          if (len < 251) {
+            baos.write((byte) len);
+          } else {
+            // assume length cannot be > 65536
+            baos.write((byte) 0xfc);
+            baos.write((byte) len);
+            baos.write((byte) (len >>> 8));
+          }
+          baos.write(bb, 0, bb.length);
+        } else {
+          baos.write((byte) 0xfb);
+        }
+      }
+      byte[] bb = baos.toByteArray();
+      rows.add(bb);
+    }
+    return new CompleteResult(columns, rows.toArray(new byte[0][0]), context);
+  }
+
+  @Override
+  public boolean next() throws SQLException {
+    if (rowPointer < dataSize - 1) {
+      setRow(data[++rowPointer]);
+      return true;
+    } else {
+      // all data are reads and pointer is after last
+      setNullRowBuf();
+      rowPointer = dataSize;
+      return false;
+    }
+  }
+
+  @Override
+  public boolean streaming() {
+    return false;
+  }
+
+  @Override
+  public void fetchRemaining() {}
+
+  @Override
+  public void closeFromStmtClose(ReentrantLock lock) {
+    this.closed = true;
+  }
+
+  @Override
+  public boolean isAfterLast() throws SQLException {
+    checkClose();
+    if (rowPointer < dataSize) {
+      // has remaining results
+      return false;
+    } else {
+
+      // has read all data and pointer is after last result
+      // so result would have to always be true,
+      // but when result contain no row at all jdbc say that must return false
+      return dataSize > 0;
+    }
+  }
+
+  @Override
+  public boolean isFirst() throws SQLException {
+    checkClose();
+    return rowPointer == 0 && dataSize > 0;
+  }
+
+  @Override
+  public boolean isLast() throws SQLException {
+    checkClose();
+    return rowPointer == dataSize - 1 && dataSize > 0;
+  }
+
+  @Override
+  public void beforeFirst() throws SQLException {
+    checkClose();
+    rowPointer = BEFORE_FIRST_POS;
+    setNullRowBuf();
+  }
+
+  @Override
+  public void afterLast() throws SQLException {
+    checkClose();
+    setNullRowBuf();
+    rowPointer = dataSize;
+  }
+
+  @Override
+  public boolean first() throws SQLException {
+    checkClose();
+    rowPointer = 0;
+    if (dataSize == 0) {
+      setNullRowBuf();
+      return false;
+    }
+    setRow(data[rowPointer]);
+    return true;
+  }
+
+  @Override
+  public boolean last() throws SQLException {
+    checkClose();
+    rowPointer = dataSize - 1;
+    if (rowPointer == BEFORE_FIRST_POS) {
+      setNullRowBuf();
+      return false;
+    }
+    setRow(data[rowPointer]);
+    return true;
+  }
+
+  @Override
+  public int getRow() throws SQLException {
+    checkClose();
+    return rowPointer == dataSize ? 0 : rowPointer + 1;
+  }
+
+  @Override
+  public boolean absolute(int idx) throws SQLException {
+    checkClose();
+    if (idx == 0 || idx > dataSize) {
+      rowPointer = idx == 0 ? BEFORE_FIRST_POS : dataSize;
+      setNullRowBuf();
+      return false;
+    }
+
+    if (idx > 0) {
+      rowPointer = idx - 1;
+      setRow(data[rowPointer]);
+      return true;
+    } else {
+      if (dataSize + idx >= 0) {
+        // absolute position reverse from ending resultSet
+        rowPointer = dataSize + idx;
+        setRow(data[rowPointer]);
+        return true;
+      }
+      rowPointer = BEFORE_FIRST_POS;
+      setNullRowBuf();
+      return false;
+    }
+  }
+
+  @Override
+  public boolean relative(int rows) throws SQLException {
+    checkClose();
+    int newPos = rowPointer + rows;
+    if (newPos <= -1) {
+      rowPointer = BEFORE_FIRST_POS;
+      setNullRowBuf();
+      return false;
+    } else if (newPos >= dataSize) {
+      rowPointer = dataSize;
+      setNullRowBuf();
+      return false;
+    } else {
+      rowPointer = newPos;
+      setRow(data[rowPointer]);
+      return true;
+    }
+  }
+
+  @Override
+  public boolean previous() throws SQLException {
+    checkClose();
+    if (rowPointer > BEFORE_FIRST_POS) {
+      rowPointer--;
+      if (rowPointer != BEFORE_FIRST_POS) {
+        setRow(data[rowPointer]);
+        return true;
+      }
+    }
+    setNullRowBuf();
+    return false;
+  }
+
+  @Override
+  public int getFetchSize() throws SQLException {
+    checkClose();
+    return 0;
+  }
+
+  @Override
+  public void setFetchSize(int rows) throws SQLException {
+    checkClose();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/Result.java b/src/main/java/org/mariadb/jdbc/client/result/Result.java
new file mode 100644
index 0000000..1ed6171
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/Result.java
@@ -0,0 +1,1718 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.result;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.sql.*;
+import java.sql.Date;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.result.rowdecoder.BinaryRowDecoder;
+import org.mariadb.jdbc.client.result.rowdecoder.RowDecoder;
+import org.mariadb.jdbc.client.result.rowdecoder.TextRowDecoder;
+import org.mariadb.jdbc.client.util.MutableInt;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.server.ErrorPacket;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.plugin.codec.*;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Result-set common */
+public abstract class Result implements ResultSet, Completion {
+  private static BinaryRowDecoder BINARY_ROW_DECODER = new BinaryRowDecoder();
+  private static TextRowDecoder TEXT_ROW_DECODER = new TextRowDecoder();
+  /** null length value */
+  public static final int NULL_LENGTH = -1;
+
+  private final int maxIndex;
+  private final boolean closeOnCompletion;
+  private boolean forceAlias;
+  private final boolean traceEnable;
+
+  /** result-set type */
+  protected final int resultSetType;
+
+  /** connection exception factory */
+  protected final ExceptionFactory exceptionFactory;
+
+  /** packet reader */
+  protected final org.mariadb.jdbc.client.socket.Reader reader;
+
+  /** connection context */
+  protected final Context context;
+
+  /** columns metadata */
+  protected final ColumnDecoder[] metadataList;
+
+  /** binary/text row decoder */
+  protected final RowDecoder rowDecoder;
+
+  /** data size */
+  protected int dataSize = 0;
+
+  /** rows */
+  protected byte[][] data;
+
+  private byte[] nullBitmap;
+
+  /** reusable row buffer decoder */
+  protected final StandardReadableByteBuf rowBuf = new StandardReadableByteBuf(null, 0);
+
+  private int fieldLength;
+
+  /** mutable field index */
+  protected MutableInt fieldIndex = new MutableInt();
+
+  private Map<String, Integer> mapper = null;
+
+  /** is fully loaded */
+  protected boolean loaded;
+
+  /** is an output parameter result-set */
+  protected boolean outputParameter;
+
+  /** current row pointer */
+  protected int rowPointer = -1;
+
+  /** is result-set closed */
+  protected boolean closed;
+
+  /** statement that initiate this result */
+  protected Statement statement;
+
+  /** row number limit */
+  protected long maxRows;
+
+  /**
+   * Constructor for server's data
+   *
+   * @param stmt statement that initiate this result
+   * @param binaryProtocol binary encoded rows
+   * @param maxRows row number limit
+   * @param metadataList columns metadata
+   * @param reader packet reader
+   * @param context connection context
+   * @param resultSetType result-set type
+   * @param closeOnCompletion close statement on completion
+   * @param traceEnable logger enabled
+   */
+  public Result(
+      org.mariadb.jdbc.Statement stmt,
+      boolean binaryProtocol,
+      long maxRows,
+      ColumnDecoder[] metadataList,
+      org.mariadb.jdbc.client.socket.Reader reader,
+      Context context,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean traceEnable) {
+    this.maxRows = maxRows;
+    this.statement = stmt;
+    this.closeOnCompletion = closeOnCompletion;
+    this.metadataList = metadataList;
+    this.maxIndex = this.metadataList.length;
+    this.reader = reader;
+    this.exceptionFactory = context.getExceptionFactory();
+    this.context = context;
+    this.resultSetType = resultSetType;
+    this.traceEnable = traceEnable;
+    if (binaryProtocol) {
+      rowDecoder = BINARY_ROW_DECODER;
+      nullBitmap = new byte[(maxIndex + 9) / 8];
+    } else {
+      rowDecoder = TEXT_ROW_DECODER;
+    }
+  }
+
+  /**
+   * Internal constructed result-set
+   *
+   * @param metadataList column metadata
+   * @param data raw data
+   * @param context connection context
+   */
+  public Result(ColumnDecoder[] metadataList, byte[][] data, Context context) {
+    this.metadataList = metadataList;
+    this.maxIndex = this.metadataList.length;
+    this.reader = null;
+    this.loaded = true;
+    this.exceptionFactory = context.getExceptionFactory();
+    this.context = context;
+    this.data = data;
+    this.dataSize = data.length;
+    this.statement = null;
+    this.resultSetType = TYPE_FORWARD_ONLY;
+    this.closeOnCompletion = false;
+    this.traceEnable = false;
+    rowDecoder = TEXT_ROW_DECODER;
+  }
+
+  /**
+   * Read new row
+   *
+   * @return true if fully loaded
+   * @throws IOException if any socket error occurs
+   * @throws SQLException for all other type of errors
+   */
+  @SuppressWarnings("fallthrough")
+  protected boolean readNext() throws IOException, SQLException {
+    byte[] buf = reader.readPacket(traceEnable);
+    switch (buf[0]) {
+      case (byte) 0xFF:
+        loaded = true;
+        ErrorPacket errorPacket = new ErrorPacket(reader.readableBufFromArray(buf), context);
+        throw exceptionFactory.create(
+            errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
+
+      case (byte) 0xFE:
+        if ((context.isEofDeprecated() && buf.length < 16777215)
+            || (!context.isEofDeprecated() && buf.length < 8)) {
+          ReadableByteBuf readBuf = reader.readableBufFromArray(buf);
+          readBuf.skip(); // skip header
+          int serverStatus;
+          int warnings;
+
+          if (!context.isEofDeprecated()) {
+            // EOF_Packet
+            warnings = readBuf.readUnsignedShort();
+            serverStatus = readBuf.readUnsignedShort();
+          } else {
+            // OK_Packet with a 0xFE header
+            readBuf.readLongLengthEncodedNotNull(); // skip update count
+            readBuf.readLongLengthEncodedNotNull(); // skip insert id
+            serverStatus = readBuf.readUnsignedShort();
+            warnings = readBuf.readUnsignedShort();
+          }
+          outputParameter = (serverStatus & ServerStatus.PS_OUT_PARAMETERS) != 0;
+          context.setServerStatus(serverStatus);
+          context.setWarning(warnings);
+          loaded = true;
+          return false;
+        }
+
+        // continue reading rows
+
+      default:
+        if (dataSize + 1 > data.length) {
+          growDataArray();
+        }
+        data[dataSize++] = buf;
+    }
+    return true;
+  }
+
+  /**
+   * Skip remaining rows to keep connection state ok, without needing remaining data.
+   *
+   * @throws IOException if socket error occurs
+   * @throws SQLException for other kind of error
+   */
+  @SuppressWarnings("fallthrough")
+  protected void skipRemaining() throws IOException, SQLException {
+    while (true) {
+      ReadableByteBuf buf = reader.readReusablePacket(traceEnable);
+      switch (buf.getUnsignedByte()) {
+        case 0xFF:
+          loaded = true;
+          ErrorPacket errorPacket = new ErrorPacket(buf, context);
+          throw exceptionFactory.create(
+              errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
+
+        case 0xFE:
+          if ((context.isEofDeprecated() && buf.readableBytes() < 0xffffff)
+              || (!context.isEofDeprecated() && buf.readableBytes() < 8)) {
+
+            buf.skip(); // skip header
+            int serverStatus;
+            int warnings;
+
+            if (!context.isEofDeprecated()) {
+              // EOF_Packet
+              warnings = buf.readUnsignedShort();
+              serverStatus = buf.readUnsignedShort();
+            } else {
+              // OK_Packet with a 0xFE header
+              buf.readLongLengthEncodedNotNull(); // skip update count
+              buf.readLongLengthEncodedNotNull(); // skip insert id
+              serverStatus = buf.readUnsignedShort();
+              warnings = buf.readUnsignedShort();
+            }
+            outputParameter = (serverStatus & ServerStatus.PS_OUT_PARAMETERS) != 0;
+            context.setServerStatus(serverStatus);
+            context.setWarning(warnings);
+            loaded = true;
+            return;
+          }
+      }
+    }
+  }
+
+  /** Grow data array. */
+  private void growDataArray() {
+    int newCapacity = data.length + (data.length >> 1);
+    byte[][] newData = new byte[newCapacity][];
+    System.arraycopy(data, 0, newData, 0, data.length);
+    data = newData;
+  }
+
+  /**
+   * Position resultset to next row
+   *
+   * @return true if next row exists
+   * @throws SQLException if any error occurs
+   */
+  @Override
+  public abstract boolean next() throws SQLException;
+
+  /**
+   * Indicate of current result-set is a streaming result-set
+   *
+   * @return if streaming result-set
+   */
+  public abstract boolean streaming();
+
+  /**
+   * Fetch remaining results.
+   *
+   * @throws SQLException if issue occurs during data retrieving
+   */
+  public abstract void fetchRemaining() throws SQLException;
+
+  /**
+   * Is result-set fully loaded or still streaming
+   *
+   * @return true if fully loaded
+   */
+  public boolean loaded() {
+    return loaded;
+  }
+
+  /**
+   * Does result-set contain output parameters
+   *
+   * @return true if containing output parameters
+   */
+  public boolean isOutputParameter() {
+    return outputParameter;
+  }
+
+  /**
+   * Close current result-set
+   *
+   * @throws SQLException if socket error occurs
+   */
+  @Override
+  public void close() throws SQLException {
+    if (!loaded) {
+      try {
+        skipRemaining();
+      } catch (IOException ioe) {
+        throw exceptionFactory.create("Error while streaming resultSet data", "08000", ioe);
+      }
+    }
+    this.closed = true;
+    if (closeOnCompletion) {
+      statement.close();
+    }
+  }
+
+  /**
+   * Closing result-set due to closing statement that issue command.
+   *
+   * @param lock thread locker object
+   * @throws SQLException if any error occurs
+   */
+  public void closeFromStmtClose(ReentrantLock lock) throws SQLException {
+    lock.lock();
+    try {
+      this.fetchRemaining();
+      this.closed = true;
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  /** Aborting result-set, without any consideration for connection state. */
+  public void abort() {
+    this.closed = true;
+  }
+
+  /**
+   * return current row RAW data
+   *
+   * @return current row RAW data
+   */
+  protected byte[] getCurrentRowData() {
+    return data[0];
+  }
+
+  /**
+   * Add a row
+   *
+   * @param buf add row
+   */
+  protected void addRowData(byte[] buf) {
+    if (dataSize + 1 > data.length) {
+      growDataArray();
+    }
+    data[dataSize++] = buf;
+  }
+
+  /**
+   * Update current row
+   *
+   * @param rawData new row
+   */
+  protected void updateRowData(byte[] rawData) {
+    data[rowPointer] = rawData;
+    if (rawData == null) {
+      setNullRowBuf();
+    } else {
+      setRow(rawData);
+      fieldIndex.set(-1);
+    }
+  }
+
+  private void checkIndex(int index) throws SQLException {
+    if (index < 1 || index > maxIndex) {
+      throw new SQLException(
+          String.format("Wrong index position. Is %s but must be in 1-%s range", index, maxIndex));
+    }
+    if (rowBuf.buf == null) {
+      throw new SQLDataException("wrong row position", "22023");
+    }
+  }
+
+  /**
+   * has last data getter return a null value
+   *
+   * @return true if was null
+   */
+  @Override
+  public boolean wasNull() {
+    return rowDecoder.wasNull(nullBitmap, fieldIndex, fieldLength);
+  }
+
+  @Override
+  public String getString(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decodeString(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  public boolean getBoolean(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return false;
+    }
+    return rowDecoder.decodeBoolean(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  public byte getByte(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return 0;
+    }
+    return rowDecoder.decodeByte(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  public short getShort(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return 0;
+    }
+    return rowDecoder.decodeShort(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  public int getInt(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return 0;
+    }
+    return rowDecoder.decodeInt(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  public long getLong(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return 0L;
+    }
+    return rowDecoder.decodeLong(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  /**
+   * Retrieves the value of the designated column in the current row of this ResultSet object as a
+   * BigInteger.
+   *
+   * @param columnIndex index
+   * @return BigInteger value
+   * @throws SQLException if cannot be decoded as a BigInteger
+   */
+  public BigInteger getBigInteger(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        BigIntegerCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  /**
+   * Retrieves the value of the designated column in the current row of this ResultSet object as a
+   * BigInteger.
+   *
+   * @param columnLabel column label
+   * @return BigInteger value
+   * @throws SQLException if cannot be decoded as a BigInteger
+   */
+  public BigInteger getBigInteger(String columnLabel) throws SQLException {
+    return getBigInteger(findColumn(columnLabel));
+  }
+
+  @Override
+  public float getFloat(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return 0F;
+    }
+    return rowDecoder.decodeFloat(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  public double getDouble(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return 0D;
+    }
+    return rowDecoder.decodeDouble(metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  @Deprecated
+  public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    BigDecimal d =
+        rowDecoder.decode(
+            BigDecimalCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+    if (d == null) return null;
+    return d.setScale(scale, RoundingMode.HALF_DOWN);
+  }
+
+  @Override
+  public byte[] getBytes(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        ByteArrayCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public Date getDate(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decodeDate(metadataList, fieldIndex, rowBuf, fieldLength, null);
+  }
+
+  @Override
+  public Time getTime(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decodeTime(metadataList, fieldIndex, rowBuf, fieldLength, null);
+  }
+
+  @Override
+  public Timestamp getTimestamp(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decodeTimestamp(metadataList, fieldIndex, rowBuf, fieldLength, null);
+  }
+
+  @Override
+  public InputStream getAsciiStream(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        StreamCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  @Deprecated
+  public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        StreamCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public InputStream getBinaryStream(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        StreamCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public String getString(String columnLabel) throws SQLException {
+    return getString(findColumn(columnLabel));
+  }
+
+  @Override
+  public boolean getBoolean(String columnLabel) throws SQLException {
+    return getBoolean(findColumn(columnLabel));
+  }
+
+  @Override
+  public byte getByte(String columnLabel) throws SQLException {
+    return getByte(findColumn(columnLabel));
+  }
+
+  @Override
+  public short getShort(String columnLabel) throws SQLException {
+    return getShort(findColumn(columnLabel));
+  }
+
+  @Override
+  public int getInt(String columnLabel) throws SQLException {
+    return getInt(findColumn(columnLabel));
+  }
+
+  @Override
+  public long getLong(String columnLabel) throws SQLException {
+    return getLong(findColumn(columnLabel));
+  }
+
+  @Override
+  public float getFloat(String columnLabel) throws SQLException {
+    return getFloat(findColumn(columnLabel));
+  }
+
+  @Override
+  public double getDouble(String columnLabel) throws SQLException {
+    return getDouble(findColumn(columnLabel));
+  }
+
+  @Override
+  @Deprecated
+  public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
+    return getBigDecimal(findColumn(columnLabel), scale);
+  }
+
+  @Override
+  public byte[] getBytes(String columnLabel) throws SQLException {
+    return getBytes(findColumn(columnLabel));
+  }
+
+  @Override
+  public Date getDate(String columnLabel) throws SQLException {
+    return getDate(findColumn(columnLabel));
+  }
+
+  @Override
+  public Time getTime(String columnLabel) throws SQLException {
+    return getTime(findColumn(columnLabel));
+  }
+
+  @Override
+  public Timestamp getTimestamp(String columnLabel) throws SQLException {
+    return getTimestamp(findColumn(columnLabel));
+  }
+
+  @Override
+  public InputStream getAsciiStream(String columnLabel) throws SQLException {
+    return getAsciiStream(findColumn(columnLabel));
+  }
+
+  @Override
+  @Deprecated
+  public InputStream getUnicodeStream(String columnLabel) throws SQLException {
+    return getUnicodeStream(findColumn(columnLabel));
+  }
+
+  @Override
+  public InputStream getBinaryStream(String columnLabel) throws SQLException {
+    return getBinaryStream(findColumn(columnLabel));
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    if (this.statement == null) {
+      return null;
+    }
+    return this.statement.getWarnings();
+  }
+
+  @Override
+  public void clearWarnings() throws SQLException {
+    if (this.statement != null) {
+      this.statement.clearWarnings();
+    }
+  }
+
+  @Override
+  public String getCursorName() throws SQLException {
+    throw exceptionFactory.notSupported("Cursors are not supported");
+  }
+
+  @Override
+  public ResultSetMetaData getMetaData() {
+    return new ResultSetMetaData(exceptionFactory, metadataList, context.getConf(), forceAlias);
+  }
+
+  @Override
+  public Object getObject(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.defaultDecode(
+        context.getConf(), metadataList, fieldIndex, rowBuf, fieldLength);
+  }
+
+  @Override
+  public Object getObject(String columnLabel) throws SQLException {
+    return getObject(findColumn(columnLabel));
+  }
+
+  @Override
+  public Reader getCharacterStream(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        ReaderCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public Reader getCharacterStream(String columnLabel) throws SQLException {
+    return getCharacterStream(findColumn(columnLabel));
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        BigDecimalCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
+    return getBigDecimal(findColumn(columnLabel));
+  }
+
+  /**
+   * Verify that result-set is not closed, throwing an exception if closed
+   *
+   * @throws SQLException if closed
+   */
+  protected void checkClose() throws SQLException {
+    if (closed) {
+      throw exceptionFactory.create("Operation not permit on a closed resultSet", "HY000");
+    }
+  }
+
+  /**
+   * Throw an exception if result-set type is ResultSet.TYPE_FORWARD_ONLY
+   *
+   * @throws SQLException throw error if type is ResultSet.TYPE_FORWARD_ONLY
+   */
+  protected void checkNotForwardOnly() throws SQLException {
+    if (resultSetType == ResultSet.TYPE_FORWARD_ONLY) {
+      throw exceptionFactory.create("Operation not permit on TYPE_FORWARD_ONLY resultSet", "HY000");
+    }
+  }
+
+  @Override
+  public boolean isBeforeFirst() throws SQLException {
+    checkClose();
+    return rowPointer == -1 && dataSize > 0;
+  }
+
+  @Override
+  public abstract boolean isAfterLast() throws SQLException;
+
+  @Override
+  public abstract boolean isFirst() throws SQLException;
+
+  @Override
+  public abstract boolean isLast() throws SQLException;
+
+  @Override
+  public abstract void beforeFirst() throws SQLException;
+
+  @Override
+  public abstract void afterLast() throws SQLException;
+
+  @Override
+  public abstract boolean first() throws SQLException;
+
+  @Override
+  public abstract boolean last() throws SQLException;
+
+  @Override
+  public abstract int getRow() throws SQLException;
+
+  @Override
+  public abstract boolean absolute(int row) throws SQLException;
+
+  @Override
+  public abstract boolean relative(int rows) throws SQLException;
+
+  @Override
+  public abstract boolean previous() throws SQLException;
+
+  @Override
+  public int getFetchDirection() {
+    return FETCH_UNKNOWN;
+  }
+
+  @Override
+  public void setFetchDirection(int direction) throws SQLException {
+    if (direction == FETCH_REVERSE) {
+      throw exceptionFactory.create(
+          "Invalid operation. Allowed direction are ResultSet.FETCH_FORWARD and"
+              + " ResultSet.FETCH_UNKNOWN");
+    }
+  }
+
+  @Override
+  public int getType() {
+    return resultSetType;
+  }
+
+  @Override
+  public int getConcurrency() {
+    return CONCUR_READ_ONLY;
+  }
+
+  @Override
+  public boolean rowUpdated() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public boolean rowInserted() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public boolean rowDeleted() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNull(int columnIndex) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateByte(int columnIndex, byte x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateShort(int columnIndex, short x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateInt(int columnIndex, int x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateLong(int columnIndex, long x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateFloat(int columnIndex, float x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateDouble(int columnIndex, double x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateString(int columnIndex, String x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateDate(int columnIndex, Date x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateTime(int columnIndex, Time x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNull(String columnLabel) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBoolean(String columnLabel, boolean x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateByte(String columnLabel, byte x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateShort(String columnLabel, short x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateInt(String columnLabel, int x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateLong(String columnLabel, long x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateFloat(String columnLabel, float x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateDouble(String columnLabel, double x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateString(String columnLabel, String x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateDate(String columnLabel, Date x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateTime(String columnLabel, Time x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream x, int length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader, int length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void insertRow() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateRow() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void deleteRow() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void refreshRow() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void cancelRowUpdates() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void moveToInsertRow() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void moveToCurrentRow() throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public Statement getStatement() {
+    return statement;
+  }
+
+  /**
+   * Update statement that initiate this result-set
+   *
+   * @param stmt statement
+   */
+  public void setStatement(Statement stmt) {
+    statement = stmt;
+  }
+
+  /** Force using alias as name */
+  public void useAliasAsName() {
+    for (Column packet : metadataList) {
+      packet.useAliasAsName();
+    }
+    forceAlias = true;
+  }
+
+  @Override
+  public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
+    if (map == null || map.isEmpty()) {
+      return getObject(columnIndex);
+    }
+    throw exceptionFactory.notSupported(
+        "Method ResultSet.getObject(int columnIndex, Map<String, Class<?>> map) not supported for"
+            + " non empty map");
+  }
+
+  @Override
+  public Ref getRef(int columnIndex) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.getRef not supported");
+  }
+
+  @Override
+  public Blob getBlob(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        BlobCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public Clob getClob(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        ClobCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public Array getArray(int columnIndex) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.getArray not supported");
+  }
+
+  @Override
+  public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
+    if (map == null || map.isEmpty()) {
+      return getObject(columnLabel);
+    }
+    throw exceptionFactory.notSupported(
+        "Method ResultSet.getObject(String columnLabel, Map<String, Class<?>> map) not supported");
+  }
+
+  @Override
+  public Ref getRef(String columnLabel) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.getRef not supported");
+  }
+
+  @Override
+  public Blob getBlob(String columnLabel) throws SQLException {
+    return getBlob(findColumn(columnLabel));
+  }
+
+  @Override
+  public Clob getClob(String columnLabel) throws SQLException {
+    return getClob(findColumn(columnLabel));
+  }
+
+  @Override
+  public Array getArray(String columnLabel) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.getArray not supported");
+  }
+
+  @Override
+  public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decodeDate(metadataList, fieldIndex, rowBuf, fieldLength, cal);
+  }
+
+  @Override
+  public Date getDate(String columnLabel, Calendar cal) throws SQLException {
+    return getDate(findColumn(columnLabel), cal);
+  }
+
+  @Override
+  public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decodeTime(metadataList, fieldIndex, rowBuf, fieldLength, cal);
+  }
+
+  @Override
+  public Time getTime(String columnLabel, Calendar cal) throws SQLException {
+    return getTime(findColumn(columnLabel), cal);
+  }
+
+  @Override
+  public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decodeTimestamp(metadataList, fieldIndex, rowBuf, fieldLength, cal);
+  }
+
+  @Override
+  public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
+    return getTimestamp(findColumn(columnLabel), cal);
+  }
+
+  @Override
+  public URL getURL(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+
+    String s =
+        rowDecoder.decode(
+            StringCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+    if (s == null) return null;
+    try {
+      return new URL(s);
+    } catch (MalformedURLException e) {
+      throw exceptionFactory.create(String.format("Could not parse '%s' as URL", s));
+    }
+  }
+
+  @Override
+  public URL getURL(String columnLabel) throws SQLException {
+    return getURL(findColumn(columnLabel));
+  }
+
+  @Override
+  public void updateRef(int columnIndex, Ref x) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.updateRef not supported");
+  }
+
+  @Override
+  public void updateRef(String columnLabel, Ref x) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.updateRef not supported");
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, Blob x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, Blob x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Clob x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Clob x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateArray(int columnIndex, Array x) throws SQLException {
+    throw exceptionFactory.notSupported("Array are not supported");
+  }
+
+  @Override
+  public void updateArray(String columnLabel, Array x) throws SQLException {
+    throw exceptionFactory.notSupported("Array are not supported");
+  }
+
+  @Override
+  public RowId getRowId(int columnIndex) throws SQLException {
+    throw exceptionFactory.notSupported("RowId are not supported");
+  }
+
+  @Override
+  public RowId getRowId(String columnLabel) throws SQLException {
+    throw exceptionFactory.notSupported("RowId are not supported");
+  }
+
+  @Override
+  public void updateRowId(int columnIndex, RowId x) throws SQLException {
+    throw exceptionFactory.notSupported("RowId are not supported");
+  }
+
+  @Override
+  public void updateRowId(String columnLabel, RowId x) throws SQLException {
+    throw exceptionFactory.notSupported("RowId are not supported");
+  }
+
+  @Override
+  public int getHoldability() {
+    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+  @Override
+  public boolean isClosed() {
+    return closed;
+  }
+
+  @Override
+  public void updateNString(int columnIndex, String nString) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNString(String columnLabel, String nString) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public NClob getNClob(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return (NClob)
+        rowDecoder.decode(ClobCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public NClob getNClob(String columnLabel) throws SQLException {
+    return getNClob(findColumn(columnLabel));
+  }
+
+  @Override
+  public SQLXML getSQLXML(int columnIndex) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.getSQLXML not supported");
+  }
+
+  @Override
+  public SQLXML getSQLXML(String columnLabel) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.getSQLXML not supported");
+  }
+
+  @Override
+  public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.updateSQLXML not supported");
+  }
+
+  @Override
+  public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
+    throw exceptionFactory.notSupported("Method ResultSet.updateSQLXML not supported");
+  }
+
+  @Override
+  public String getNString(int columnIndex) throws SQLException {
+    return getString(columnIndex);
+  }
+
+  @Override
+  public String getNString(String columnLabel) throws SQLException {
+    return getString(columnLabel);
+  }
+
+  @Override
+  public Reader getNCharacterStream(int columnIndex) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    if (fieldLength == NULL_LENGTH) {
+      return null;
+    }
+    return rowDecoder.decode(
+        ReaderCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
+  }
+
+  @Override
+  public Reader getNCharacterStream(String columnLabel) throws SQLException {
+    return getNCharacterStream(findColumn(columnLabel));
+  }
+
+  @Override
+  public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNCharacterStream(String columnLabel, Reader reader, long length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream x, long length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream x, long length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader, long length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, InputStream inputStream, long length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, InputStream inputStream, long length)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Reader reader) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Reader reader) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, Reader reader) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
+    checkIndex(columnIndex);
+    fieldLength =
+        rowDecoder.setPosition(
+            columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
+    Calendar calendar = null;
+    if (wasNull()) {
+      if (type.isPrimitive()) {
+        throw new SQLException(
+            String.format("Cannot return null for primitive %s", type.getName()));
+      }
+      return null;
+    }
+    Configuration conf = context.getConf();
+    ColumnDecoder column = metadataList[columnIndex - 1];
+    // type generic, return "natural" java type
+    if (Object.class.equals(type) || type == null) {
+      return (T) rowDecoder.defaultDecode(conf, metadataList, fieldIndex, rowBuf, fieldLength);
+    }
+
+    for (Codec<?> codec : conf.codecs()) {
+      if (codec.canDecode(column, type)) {
+        return rowDecoder.decode(
+            (Codec<T>) codec, calendar, rowBuf, fieldLength, metadataList, fieldIndex);
+      }
+    }
+    rowBuf.skip(fieldLength);
+    throw new SQLException(
+        String.format("Type %s not supported type for %s type", type, column.getType().name()));
+  }
+
+  @Override
+  public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
+    return getObject(findColumn(columnLabel), type);
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) {
+    return iface.isInstance(this);
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x, SQLType targetSqlType) throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x, SQLType targetSqlType)
+      throws SQLException {
+    throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
+  }
+
+  /** Set row buffer to null (no row) */
+  protected void setNullRowBuf() {
+    rowBuf.buf(null, 0, 0);
+  }
+
+  /**
+   * set row decoder to current row data
+   *
+   * @param row row
+   */
+  public void setRow(byte[] row) {
+    rowBuf.buf(row, row.length, 0);
+    fieldIndex.set(-1);
+  }
+
+  public int findColumn(String label) throws SQLException {
+    if (label == null) throw new SQLException("null is not a valid label value");
+    if (mapper == null) {
+      mapper = new HashMap<>();
+      for (int i = 0; i < maxIndex; i++) {
+        Column ci = metadataList[i];
+        String columnAlias = ci.getColumnAlias();
+        if (columnAlias != null) {
+          columnAlias = columnAlias.toLowerCase(Locale.ROOT);
+          mapper.putIfAbsent(columnAlias, i + 1);
+          String tableAlias = ci.getTableAlias();
+          String tableLabel = tableAlias != null ? tableAlias : ci.getTable();
+          mapper.putIfAbsent(tableLabel.toLowerCase(Locale.ROOT) + "." + columnAlias, i + 1);
+        }
+      }
+    }
+    Integer ind = mapper.get(label.toLowerCase(Locale.ROOT));
+    if (ind == null) {
+      String keys = Arrays.toString(mapper.keySet().toArray(new String[0]));
+      throw new SQLException(String.format("Unknown label '%s'. Possible value %s", label, keys));
+    }
+    return ind;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/ResultSetMetaData.java b/src/main/java/org/mariadb/jdbc/client/result/ResultSetMetaData.java
new file mode 100644
index 0000000..2f9628c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/ResultSetMetaData.java
@@ -0,0 +1,341 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.result;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Column;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.util.constants.ColumnFlags;
+
+/** Result-set metadata */
+public class ResultSetMetaData implements java.sql.ResultSetMetaData {
+
+  private final ExceptionFactory exceptionFactory;
+  private final ColumnDecoder[] fieldPackets;
+  private final Configuration conf;
+  private final boolean forceAlias;
+
+  /**
+   * Constructor.
+   *
+   * @param exceptionFactory default exception handler
+   * @param fieldPackets column informations
+   * @param conf connection options
+   * @param forceAlias force table and column name alias as original data
+   */
+  public ResultSetMetaData(
+      final ExceptionFactory exceptionFactory,
+      final ColumnDecoder[] fieldPackets,
+      final Configuration conf,
+      final boolean forceAlias) {
+    this.exceptionFactory = exceptionFactory;
+    this.fieldPackets = fieldPackets;
+    this.conf = conf;
+    this.forceAlias = forceAlias;
+  }
+
+  /**
+   * Returns the number of columns in this <code>ResultSet</code> object.
+   *
+   * @return the number of columns
+   */
+  public int getColumnCount() {
+    return fieldPackets.length;
+  }
+
+  /**
+   * Indicates whether the designated column is automatically numbered.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if a database access error occurs
+   */
+  public boolean isAutoIncrement(final int column) throws SQLException {
+    return (getColumn(column).getFlags() & ColumnFlags.AUTO_INCREMENT) != 0;
+  }
+
+  /**
+   * Indicates whether a column's case matters.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   */
+  public boolean isCaseSensitive(final int column) {
+    return true;
+  }
+
+  /**
+   * Indicates whether the designated column can be used in a where clause.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   */
+  public boolean isSearchable(final int column) {
+    return true;
+  }
+
+  /**
+   * Indicates whether the designated column is a cash value.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   */
+  public boolean isCurrency(final int column) {
+    return false;
+  }
+
+  /**
+   * Indicates the nullability of values in the designated column.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return the nullability status of the given column; one of <code>columnNoNulls</code>, <code>
+   *     columnNullable</code> or <code>columnNullableUnknown</code>
+   * @throws SQLException if a database access error occurs
+   */
+  public int isNullable(final int column) throws SQLException {
+    if ((getColumn(column).getFlags() & ColumnFlags.NOT_NULL) == 0) {
+      return java.sql.ResultSetMetaData.columnNullable;
+    } else {
+      return java.sql.ResultSetMetaData.columnNoNulls;
+    }
+  }
+
+  /**
+   * Indicates whether values in the designated column are signed numbers.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if a database access error occurs
+   */
+  public boolean isSigned(int column) throws SQLException {
+    return getColumn(column).isSigned();
+  }
+
+  /**
+   * Indicates the designated column's normal maximum width in characters.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return the normal maximum number of characters allowed as the width of the designated column
+   * @throws SQLException if a database access error occurs
+   */
+  public int getColumnDisplaySize(final int column) throws SQLException {
+    return getColumn(column).getDisplaySize();
+  }
+
+  /**
+   * Gets the designated column's suggested title for use in printouts and displays. The suggested
+   * title is usually specified by the SQL <code>AS</code> clause. If an SQL <code>AS</code> is not
+   * specified, the value returned from <code>getColumnLabel</code> will be the same as the value
+   * returned by the <code>getColumnName</code> method.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return the suggested column title
+   * @throws SQLException if a database access error occurs
+   */
+  public String getColumnLabel(final int column) throws SQLException {
+    return getColumn(column).getColumnAlias();
+  }
+
+  /**
+   * Get the designated column's name.
+   *
+   * @param idx the first column is 1, the second is 2, ...
+   * @return column name
+   * @throws SQLException if a database access error occurs
+   */
+  public String getColumnName(final int idx) throws SQLException {
+    Column column = getColumn(idx);
+    String columnName = column.getColumnName();
+    if ("".equals(columnName) || forceAlias) {
+      return column.getColumnAlias();
+    }
+    return columnName;
+  }
+
+  /**
+   * Get the designated column's table's schema.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return schema name or "" if not applicable
+   * @throws SQLException if a database access error occurs
+   */
+  public String getCatalogName(int column) throws SQLException {
+    return getColumn(column).getSchema();
+  }
+
+  /**
+   * Get the designated column's specified column size. For numeric data, this is the maximum
+   * precision. For character data, this is the length in characters. For datetime datatypes, this
+   * is the length in characters of the String representation (assuming the maximum allowed
+   * precision of the fractional seconds component). For binary data, this is the length in bytes.
+   * For the ROWID datatype, this is the length in bytes. 0 is returned for data types where the
+   * column size is not applicable.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return precision
+   * @throws SQLException if a database access error occurs
+   */
+  public int getPrecision(final int column) throws SQLException {
+    return getColumn(column).getPrecision();
+  }
+
+  /**
+   * Gets the designated column's number of digits to right of the decimal point. 0 is returned for
+   * data types where the scale is not applicable.
+   *
+   * @param index the first column is 1, the second is 2, ...
+   * @return scale
+   * @throws SQLException if a database access error occurs
+   */
+  public int getScale(final int index) throws SQLException {
+    return getColumn(index).getDecimals();
+  }
+
+  /**
+   * Gets the designated column's table name.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return table name or "" if not applicable
+   * @throws SQLException if a database access error occurs
+   */
+  public String getTableName(final int column) throws SQLException {
+    if (forceAlias) {
+      return getColumn(column).getTableAlias();
+    }
+
+    if (conf.blankTableNameMeta()) {
+      return "";
+    }
+
+    return getColumn(column).getTable();
+  }
+
+  public String getSchemaName(int column) {
+    return "";
+  }
+
+  /**
+   * Retrieves the designated column's SQL type.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return SQL type from java.sql.Types
+   * @throws SQLException if a database access error occurs
+   * @see Types
+   */
+  public int getColumnType(final int column) throws SQLException {
+    return getColumn(column).getColumnType(conf);
+  }
+
+  /**
+   * Retrieves the designated column's database-specific type name.
+   *
+   * @param index the first column is 1, the second is 2, ...
+   * @return type name used by the database. If the column type is a user-defined type, then a
+   *     fully-qualified type name is returned.
+   * @throws SQLException if a database access error occurs
+   */
+  public String getColumnTypeName(final int index) throws SQLException {
+    return getColumn(index).getColumnTypeName(conf);
+  }
+
+  /**
+   * Indicates whether the designated column is definitely not writable.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if a database access error occurs or in case of wrong index
+   */
+  public boolean isReadOnly(final int column) throws SQLException {
+    Column ci = getColumn(column);
+    return ci.getColumnName().isEmpty();
+  }
+
+  /**
+   * Indicates whether it is possible for writing on the designated column to succeed.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if a database access error occurs or in case of wrong index
+   */
+  public boolean isWritable(final int column) throws SQLException {
+    return !isReadOnly(column);
+  }
+
+  /**
+   * Indicates whether writing on the designated column will definitely succeed.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return <code>true</code> if so; <code>false</code> otherwise
+   * @throws SQLException if a database access error occurs or in case of wrong index
+   */
+  public boolean isDefinitelyWritable(final int column) throws SQLException {
+    return !isReadOnly(column);
+  }
+
+  /**
+   * Returns the fully-qualified name of the Java class whose instances are manufactured if the
+   * method <code>ResultSet.getObject</code> is called to retrieve a value from the column. <code>
+   * ResultSet.getObject</code> may return a subclass of the class returned by this method.
+   *
+   * @param column the first column is 1, the second is 2, ...
+   * @return the fully-qualified name of the class in the Java programming language that would be
+   *     used by the method <code>ResultSet.getObject</code> to retrieve the value in the specified
+   *     column. This is the class name used for custom mapping.
+   * @throws SQLException if a database access error occurs
+   */
+  public String getColumnClassName(int column) throws SQLException {
+    return getColumn(column).defaultClassname(conf);
+  }
+
+  private ColumnDecoder getColumn(int column) throws SQLException {
+    if (column >= 1 && column <= fieldPackets.length) {
+      return fieldPackets[column - 1];
+    }
+    throw exceptionFactory.create(String.format("wrong column index %s", column));
+  }
+
+  /**
+   * Returns an object that implements the given interface to allow access to non-standard methods,
+   * or standard methods not exposed by the proxy. <br>
+   * If the receiver implements the interface then the result is the receiver or a proxy for the
+   * receiver. If the receiver is a wrapper and the wrapped object implements the interface then the
+   * result is the wrapped object or a proxy for the wrapped object. Otherwise, return the result of
+   * calling <code>unwrap</code> recursively on the wrapped object or a proxy for that result. If
+   * the receiver is not a wrapper and does not implement the interface, then an <code>SQLException
+   * </code> is thrown.
+   *
+   * @param iface A Class defining an interface that the result must implement.
+   * @return an object that implements the interface. Maybe a proxy for the actual implementing
+   *     object.
+   * @throws SQLException If no object found that implements the interface
+   */
+  public <T> T unwrap(final Class<T> iface) throws SQLException {
+    if (isWrapperFor(iface)) {
+      return iface.cast(this);
+    }
+    throw new SQLException("The receiver is not a wrapper for " + iface.getName());
+  }
+
+  /**
+   * Returns true if this either implements the interface argument or is directly or indirectly a
+   * wrapper for an object that does. Returns false otherwise. If this implements the interface then
+   * return true, else if this is a wrapper then return the result of recursively calling <code>
+   * isWrapperFor</code> on the wrapped object. If this does not implement the interface and is not
+   * a wrapper, return false. This method should be implemented as a low-cost operation compared to
+   * <code>unwrap</code> so that callers can use this method to avoid expensive <code>unwrap</code>
+   * calls that may fail. If this method returns true then calling <code>unwrap</code> with the same
+   * argument should succeed.
+   *
+   * @param iface a Class defining an interface.
+   * @return true if this implements the interface or directly or indirectly wraps an object that
+   *     does.
+   */
+  public boolean isWrapperFor(final Class<?> iface) {
+    return iface.isInstance(this);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/StreamingResult.java b/src/main/java/org/mariadb/jdbc/client/result/StreamingResult.java
new file mode 100644
index 0000000..24678c6
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/StreamingResult.java
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.result;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Reader;
+
+/**
+ * Streaming result-set implementation. Implementation rely on reading as many rows than fetch size
+ * required, keeping remaining rows in TCP-IP buffer
+ *
+ * <p>The server usually expects clients to read off the result set relatively quickly. The
+ * net_write_timeout server variable controls this behavior (defaults to 60s).
+ *
+ * <p>If you don't expect results to be handled in this amount of time there is a different
+ * possibility:
+ *
+ * <ul>
+ *   <li>With &gt; MariaDB server, you can use the query "SET STATEMENT net_write_timeout=10000 FOR
+ *       XXX" with XXX your "normal" query. This will indicate that specifically for this query,
+ *       net_write_timeout will be set to a longer time (10000 in this example).
+ *   <li>for non mariadb servers, a specific query will have to temporarily set net_write_timeout
+ *       ("SET STATEMENT net_write_timeout=..."), and set it back afterward.
+ *   <li>if your application usually uses a lot of long queries with fetch size, the connection can
+ *       be set using option "sessionVariables=net_write_timeout=xxx"
+ * </ul>
+ *
+ * <p>Even using setFetchSize, the server will send all results to the client.
+ *
+ * <p>If another query is executed on the same connection when a streaming result-set has not been
+ * fully read, the connector will put the whole remaining streaming result-set in memory in order to
+ * execute the next query. This can lead to OutOfMemoryError if not handled.
+ */
+public class StreamingResult extends Result {
+
+  private final ReentrantLock lock;
+  private int dataFetchTime;
+  private int fetchSize;
+
+  /**
+   * Constructor
+   *
+   * @param stmt statement that initiate this result
+   * @param binaryProtocol is result-set binary encoded
+   * @param maxRows maximum row number
+   * @param metadataList column metadata
+   * @param reader packet reader
+   * @param context connection context
+   * @param fetchSize fetch size
+   * @param lock thread safe locker
+   * @param resultSetType result-set type
+   * @param closeOnCompletion close statement on completion
+   * @param traceEnable can network log be logged
+   * @throws SQLException if any error occurs
+   */
+  public StreamingResult(
+      Statement stmt,
+      boolean binaryProtocol,
+      long maxRows,
+      ColumnDecoder[] metadataList,
+      Reader reader,
+      Context context,
+      int fetchSize,
+      ReentrantLock lock,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean traceEnable)
+      throws SQLException {
+
+    super(
+        stmt,
+        binaryProtocol,
+        maxRows,
+        metadataList,
+        reader,
+        context,
+        resultSetType,
+        closeOnCompletion,
+        traceEnable);
+    this.lock = lock;
+    this.dataFetchTime = 0;
+    this.fetchSize = fetchSize;
+    this.data = new byte[Math.max(fetchSize, 10)][];
+
+    addStreamingValue();
+  }
+
+  @Override
+  public boolean streaming() {
+    return true;
+  }
+
+  /**
+   * This permit to replace current stream results by next ones.
+   *
+   * @throws SQLException if server return an unexpected error
+   */
+  private void nextStreamingValue() throws SQLException {
+
+    // if resultSet can be back to some previous value
+    if (resultSetType == TYPE_FORWARD_ONLY) {
+      rowPointer = 0;
+      dataSize = 0;
+    }
+
+    addStreamingValue();
+  }
+
+  private void addStreamingValue() throws SQLException {
+    lock.lock();
+    try {
+      // read only fetchSize values
+      int fetchSizeTmp =
+          (maxRows <= 0)
+              ? fetchSize
+              : Math.min(fetchSize, Math.max(0, (int) (maxRows - dataFetchTime * fetchSize)));
+      while (fetchSizeTmp > 0 && readNext()) {
+        fetchSizeTmp--;
+      }
+      dataFetchTime++;
+      if (maxRows > 0 && (long) dataFetchTime * fetchSize >= maxRows && !loaded) skipRemaining();
+    } catch (IOException ioe) {
+      throw exceptionFactory.create("Error while streaming resultSet data", "08000", ioe);
+    } finally {
+      lock.unlock();
+    }
+  }
+
+  /**
+   * When protocol has a current Streaming result (this) fetch all to permit another query is
+   * executing.
+   *
+   * @throws SQLException if any error occur
+   */
+  public void fetchRemaining() throws SQLException {
+    if (!loaded) {
+      while (!loaded) {
+        addStreamingValue();
+      }
+      dataFetchTime++;
+    }
+  }
+
+  @Override
+  public boolean next() throws SQLException {
+    checkClose();
+    if (rowPointer < dataSize - 1) {
+      rowPointer++;
+      setRow(data[rowPointer]);
+      return true;
+    } else {
+      if (!loaded) {
+        lock.lock();
+        try {
+          if (!loaded) {
+            nextStreamingValue();
+          }
+        } finally {
+          lock.unlock();
+        }
+
+        if (resultSetType == TYPE_FORWARD_ONLY) {
+          // resultSet has been cleared. next value is pointer 0.
+          rowPointer = 0;
+          if (dataSize > 0) {
+            setRow(data[rowPointer]);
+            return true;
+          }
+        } else {
+          // cursor can move backward, so driver must keep the results.
+          // results have been added to current resultSet
+          rowPointer++;
+          if (dataSize > rowPointer) {
+            setRow(data[rowPointer]);
+            return true;
+          }
+        }
+        setNullRowBuf();
+        return false;
+      }
+
+      // all data are reads and pointer is after last
+      rowPointer = dataSize;
+      setNullRowBuf();
+      return false;
+    }
+  }
+
+  @Override
+  public boolean isAfterLast() throws SQLException {
+    checkClose();
+    if (rowPointer < dataSize) {
+      // has remaining results
+      return false;
+    } else {
+      // has read all data and pointer is after last result
+      // so result would have to always be true,
+      // but when result contain no row at all jdbc say that must return false
+      return dataSize > 0 || dataFetchTime > 1;
+    }
+  }
+
+  @Override
+  public boolean isFirst() throws SQLException {
+    checkClose();
+    if (resultSetType == TYPE_FORWARD_ONLY) {
+      return rowPointer == 0 && dataSize > 0 && dataFetchTime == 1;
+    } else {
+      return rowPointer == 0 && dataSize > 0;
+    }
+  }
+
+  @Override
+  public boolean isLast() throws SQLException {
+    checkClose();
+    if (rowPointer < dataSize - 1) {
+      return false;
+    } else if (loaded) {
+      return rowPointer == dataSize - 1 && dataSize > 0;
+    } else {
+      // when streaming and not having read all results,
+      // must read next packet to know if next packet is an EOF packet or some additional data
+      addStreamingValue();
+
+      if (loaded) {
+        // now driver is sure when data ends.
+        return rowPointer == dataSize - 1;
+      }
+
+      // There is data remaining
+      return false;
+    }
+  }
+
+  @Override
+  public void beforeFirst() throws SQLException {
+    checkClose();
+    checkNotForwardOnly();
+    setNullRowBuf();
+    rowPointer = -1;
+  }
+
+  @Override
+  public void afterLast() throws SQLException {
+    checkClose();
+    checkNotForwardOnly();
+    fetchRemaining();
+    setNullRowBuf();
+    rowPointer = dataSize;
+  }
+
+  @Override
+  public boolean first() throws SQLException {
+    checkClose();
+    checkNotForwardOnly();
+
+    rowPointer = 0;
+    if (dataSize > 0) {
+      setRow(data[rowPointer]);
+      return true;
+    }
+    setNullRowBuf();
+    return false;
+  }
+
+  @Override
+  public boolean last() throws SQLException {
+    checkClose();
+    fetchRemaining();
+    rowPointer = dataSize - 1;
+    if (dataSize > 0) {
+      setRow(data[rowPointer]);
+      return true;
+    }
+    setNullRowBuf();
+    return false;
+  }
+
+  @Override
+  public int getRow() throws SQLException {
+    checkClose();
+    if (resultSetType == TYPE_FORWARD_ONLY) {
+      return 0;
+    }
+    return rowPointer + 1;
+  }
+
+  @Override
+  public boolean absolute(int idx) throws SQLException {
+    checkClose();
+    checkNotForwardOnly();
+
+    if (idx == 0) {
+      rowPointer = -1;
+      setNullRowBuf();
+      return false;
+    }
+
+    if (idx > 0 && idx <= dataSize) {
+      rowPointer = idx - 1;
+      setRow(data[rowPointer]);
+      return true;
+    }
+
+    // if streaming, must read additional results.
+    fetchRemaining();
+
+    if (idx > 0) {
+      if (idx <= dataSize) {
+        rowPointer = idx - 1;
+        setRow(data[rowPointer]);
+        return true;
+      }
+
+      rowPointer = dataSize; // go to afterLast() position
+      setNullRowBuf();
+
+    } else {
+
+      if (dataSize + idx >= 0) {
+        // absolute position reverse from ending resultSet
+        rowPointer = dataSize + idx;
+        setRow(data[rowPointer]);
+        return true;
+      }
+      setNullRowBuf();
+      rowPointer = -1; // go to before first position
+    }
+    return false;
+  }
+
+  @Override
+  public boolean relative(int rows) throws SQLException {
+    checkClose();
+    int newPos = rowPointer + rows;
+    if (newPos <= -1) {
+      checkNotForwardOnly();
+      rowPointer = -1;
+      setNullRowBuf();
+      return false;
+    }
+
+    while (newPos >= dataSize) {
+      if (loaded) {
+        rowPointer = dataSize;
+        setNullRowBuf();
+        return false;
+      }
+      addStreamingValue();
+    }
+
+    rowPointer = newPos;
+    setRow(data[rowPointer]);
+    return true;
+  }
+
+  @Override
+  public boolean previous() throws SQLException {
+    checkClose();
+    checkNotForwardOnly();
+    if (rowPointer > -1) {
+      rowPointer--;
+      if (rowPointer != -1) {
+        setRow(data[rowPointer]);
+        return true;
+      }
+    }
+    setNullRowBuf();
+    return false;
+  }
+
+  @Override
+  public int getFetchSize() {
+    return this.fetchSize;
+  }
+
+  @Override
+  public void setFetchSize(int fetchSize) throws SQLException {
+    if (fetchSize < 0) {
+      throw exceptionFactory.create(String.format("invalid fetch size %s", fetchSize));
+    }
+    if (fetchSize == 0) {
+      // fetch all results
+      while (!loaded) {
+        addStreamingValue();
+      }
+    }
+    this.fetchSize = fetchSize;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/UpdatableResult.java b/src/main/java/org/mariadb/jdbc/client/result/UpdatableResult.java
new file mode 100644
index 0000000..0947ba9
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/UpdatableResult.java
@@ -0,0 +1,1135 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.result;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.mariadb.jdbc.BasePreparedStatement;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.Column;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.result.rowdecoder.BinaryRowDecoder;
+import org.mariadb.jdbc.codec.*;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.plugin.codec.*;
+import org.mariadb.jdbc.util.ParameterList;
+
+/** Updatable result implementation */
+public class UpdatableResult extends CompleteResult {
+  private static final int STATE_STANDARD = 0;
+  private static final int STATE_UPDATE = 1;
+  private static final int STATE_UPDATED = 2;
+  private static final int STATE_INSERT = 3;
+  private static final int STATE_INSERTED = 4;
+
+  private String database;
+  private String table;
+  private boolean canInsert;
+  private boolean canUpdate;
+  private String sqlStateError = "HY000";
+  private boolean isAutoincrementPk;
+  private int savedRowPointer;
+  private String changeError;
+  private int state = STATE_STANDARD;
+  private ParameterList parameters;
+  private String[] primaryCols;
+
+  /**
+   * Constructor
+   *
+   * @param stmt statement that initiate this result
+   * @param binaryProtocol are rows binary encoded
+   * @param maxRows maximum rows
+   * @param metadataList columns metadata
+   * @param reader packet reader
+   * @param context connection context
+   * @param resultSetType result-set type
+   * @param closeOnCompletion close on completion
+   * @param traceEnable must network exchanges be logged
+   * @throws IOException if any socket error occurs
+   * @throws SQLException for other kind of error
+   */
+  public UpdatableResult(
+      Statement stmt,
+      boolean binaryProtocol,
+      long maxRows,
+      ColumnDecoder[] metadataList,
+      org.mariadb.jdbc.client.socket.Reader reader,
+      Context context,
+      int resultSetType,
+      boolean closeOnCompletion,
+      boolean traceEnable)
+      throws IOException, SQLException {
+    super(
+        stmt,
+        binaryProtocol,
+        maxRows,
+        metadataList,
+        reader,
+        context,
+        resultSetType,
+        closeOnCompletion,
+        traceEnable);
+    checkIfUpdatable();
+    parameters = new ParameterList(metadataList.length);
+  }
+
+  private void checkIfUpdatable() throws SQLException {
+    isAutoincrementPk = false;
+    canInsert = true;
+    canUpdate = true;
+
+    // check that resultSet concern one table and database exactly
+    database = null;
+    table = null;
+    for (Column columnDefinition : metadataList) {
+      if (columnDefinition.getTable().isEmpty()) {
+        cannotUpdateInsertRow(
+            "The result-set contains fields without without any database/table information");
+        sqlStateError = "0A000";
+        return;
+      }
+
+      if (database != null && !database.equals(columnDefinition.getSchema())) {
+        cannotUpdateInsertRow("The result-set contains more than one database");
+        sqlStateError = "0A000";
+        return;
+      }
+      database = columnDefinition.getSchema();
+
+      if (table != null && !table.equals(columnDefinition.getTable())) {
+        cannotUpdateInsertRow("The result-set contains fields on different tables");
+        sqlStateError = "0A000";
+        return;
+      }
+      table = columnDefinition.getTable();
+    }
+
+    // check that listed column contain primary field
+    for (Column col : metadataList) {
+      if (col.isPrimaryKey()) {
+        isAutoincrementPk = col.isAutoIncrement();
+        if (isAutoincrementPk) {
+          primaryCols = new String[] {col.getColumnName()};
+          return;
+        }
+      }
+    }
+
+    // check that table contains a generated primary field
+    // to check if insert are still possible
+    ResultSet rs =
+        statement
+            .getConnection()
+            .createStatement()
+            .executeQuery("SHOW COLUMNS FROM `" + database + "`.`" + table + "`");
+    List<String> primaryColumns = new ArrayList<>();
+    while (rs.next()) {
+      if ("PRI".equals(rs.getString("Key"))) {
+        primaryColumns.add(rs.getString("Field"));
+        boolean keyPresent = false;
+        for (Column col : metadataList) {
+          if (rs.getString("Field").equals(col.getColumnName())) {
+            keyPresent = true;
+          }
+        }
+        boolean canBeNull = "YES".equals(rs.getString("Null"));
+        boolean hasDefault = rs.getString("Default") != null;
+        boolean generated = rs.getString("Extra") != null && !rs.getString("Extra").isEmpty();
+        isAutoincrementPk =
+            rs.getString("Extra") != null && rs.getString("Extra").contains("auto_increment");
+        if (!keyPresent && !canBeNull && !hasDefault && !generated) {
+          canInsert = false;
+          changeError =
+              String.format("primary field `%s` is not present in query", rs.getString("Field"));
+        }
+        if (!keyPresent) {
+          canUpdate = false;
+          changeError =
+              String.format(
+                  "Cannot update rows, since primary field %s is not present in query",
+                  rs.getString("Field"));
+        }
+      }
+    }
+
+    if (primaryColumns.isEmpty()) {
+      canUpdate = false;
+      changeError = "Cannot update rows, since no primary field is present in query";
+    } else {
+      primaryCols = primaryColumns.toArray(new String[0]);
+    }
+  }
+
+  private void cannotUpdateInsertRow(String reason) {
+    changeError = reason;
+    canUpdate = false;
+    canInsert = false;
+  }
+
+  private void checkUpdatable(int position) throws SQLException {
+    if (position <= 0 || position > metadataList.length) {
+      throw exceptionFactory.create("No such column: " + position, "22023");
+    }
+
+    if (state == STATE_STANDARD || state == STATE_UPDATED) {
+      state = STATE_UPDATE;
+    }
+    if (state == STATE_UPDATE) {
+      if (rowPointer <= BEFORE_FIRST_POS) {
+        throw new SQLDataException("Current position is before the first row", "22023");
+      }
+      if (rowPointer >= dataSize) {
+        throw new SQLDataException("Current position is after the last row", "22023");
+      }
+      if (!canUpdate) {
+        throw exceptionFactory.create("ResultSet cannot be updated. " + changeError, sqlStateError);
+      }
+    }
+  }
+
+  @Override
+  public boolean rowUpdated() {
+    return state == STATE_UPDATED;
+  }
+
+  @Override
+  public boolean rowInserted() {
+    return state == STATE_INSERTED;
+  }
+
+  @Override
+  public boolean rowDeleted() {
+    return false;
+  }
+
+  @Override
+  public void updateNull(int columnIndex) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, Parameter.NULL_PARAMETER);
+  }
+
+  @Override
+  public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(BooleanCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateByte(int columnIndex, byte x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ByteCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateShort(int columnIndex, short x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ShortCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateInt(int columnIndex, int x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(IntCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateLong(int columnIndex, long x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(LongCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateFloat(int columnIndex, float x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(FloatCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateDouble(int columnIndex, double x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(DoubleCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(BigDecimalCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateString(int columnIndex, String x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StringCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ByteArrayCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateDate(int columnIndex, Date x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(DateCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateTime(int columnIndex, Time x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(TimeCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(TimestampCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length));
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length));
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, x, (long) length));
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
+    updateInternalObject(columnIndex, x, (long) scaleOrLength);
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x) throws SQLException {
+    updateInternalObject(columnIndex, x, null);
+  }
+
+  @Override
+  public void updateNull(String columnLabel) throws SQLException {
+    updateNull(findColumn(columnLabel));
+  }
+
+  @Override
+  public void updateBoolean(String columnLabel, boolean x) throws SQLException {
+    updateBoolean(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateByte(String columnLabel, byte x) throws SQLException {
+    updateByte(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateShort(String columnLabel, short x) throws SQLException {
+    updateShort(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateInt(String columnLabel, int x) throws SQLException {
+    updateInt(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateLong(String columnLabel, long x) throws SQLException {
+    updateLong(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateFloat(String columnLabel, float x) throws SQLException {
+    updateFloat(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateDouble(String columnLabel, double x) throws SQLException {
+    updateDouble(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
+    updateBigDecimal(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateString(String columnLabel, String x) throws SQLException {
+    updateString(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+    updateBytes(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateDate(String columnLabel, Date x) throws SQLException {
+    updateDate(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateTime(String columnLabel, Time x) throws SQLException {
+    updateTime(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
+    updateTimestamp(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
+    updateAsciiStream(findColumn(columnLabel), x, length);
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream x, int length)
+      throws SQLException {
+    updateBinaryStream(findColumn(columnLabel), x, length);
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader, int length)
+      throws SQLException {
+    updateCharacterStream(findColumn(columnLabel), reader, length);
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
+    updateObject(findColumn(columnLabel), x, scaleOrLength);
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x) throws SQLException {
+    updateObject(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void insertRow() throws SQLException {
+    if (state == STATE_INSERT || state == STATE_INSERTED) {
+
+      // Create query will all field with WHERE clause contain primary field.
+      // if field are not updated, value DEFAULT will be set
+      // (if field has no default, then insert will throw an exception that will be return to
+      // user)
+
+      String insertSql = buildInsertQuery();
+      try (PreparedStatement insertPreparedStatement =
+          ((Connection) statement.getConnection())
+              .prepareInternal(
+                  insertSql,
+                  Statement.RETURN_GENERATED_KEYS,
+                  ResultSet.TYPE_FORWARD_ONLY,
+                  ResultSet.CONCUR_READ_ONLY,
+                  rowDecoder instanceof BinaryRowDecoder)) {
+
+        int paramPos = 0;
+        for (int pos = 0; pos < metadataList.length; pos++) {
+          Column colInfo = metadataList[pos];
+          org.mariadb.jdbc.client.util.Parameter param =
+              parameters.size() > pos ? parameters.get(pos) : null;
+          if (param != null) {
+            ((BasePreparedStatement) insertPreparedStatement).setParameter(paramPos++, param);
+          } else if (!Arrays.asList(primaryCols).contains(colInfo.getColumnName())
+              && !colInfo.hasDefault()) {
+            ((BasePreparedStatement) insertPreparedStatement)
+                .setParameter(paramPos++, Parameter.NULL_PARAMETER);
+          }
+        }
+        ResultSet insertRs = insertPreparedStatement.executeQuery();
+        if (context.getVersion().isMariaDBServer()
+            && context.getVersion().versionGreaterOrEqual(10, 5, 1)) {
+          if (insertRs.next()) {
+            byte[] rowByte = ((Result) insertRs).getCurrentRowData();
+            addRowData(rowByte);
+          }
+        } else if (isAutoincrementPk) {
+          // primary is auto_increment (only one field)
+          ResultSet rsKey = insertPreparedStatement.getGeneratedKeys();
+          if (rsKey.next()) {
+            try (PreparedStatement refreshPreparedStatement = prepareRefreshStmt()) {
+              refreshPreparedStatement.setObject(1, rsKey.getObject(1));
+              Result rs = (Result) refreshPreparedStatement.executeQuery();
+              // update row data only if not deleted externally
+              if (rs.next()) {
+                addRowData(rs.getCurrentRowData());
+              }
+            }
+          }
+        } else {
+          addRowData(refreshRawData());
+        }
+      }
+      parameters = new ParameterList(parameters.size());
+      state = STATE_INSERTED;
+    }
+  }
+
+  /**
+   * Build insert query
+   *
+   * @return insert sql
+   * @throws SQLException exception
+   */
+  private String buildInsertQuery() throws SQLException {
+    StringBuilder insertSql = new StringBuilder("INSERT `" + database + "`.`" + table + "` ( ");
+    StringBuilder valueClause = new StringBuilder();
+    StringBuilder returningClause = new StringBuilder();
+
+    boolean firstParam = true;
+
+    for (int pos = 0; pos < metadataList.length; pos++) {
+      Column colInfo = metadataList[pos];
+
+      if (pos != 0) {
+        returningClause.append(", ");
+      }
+      returningClause.append("`").append(colInfo.getColumnName()).append("`");
+
+      org.mariadb.jdbc.client.util.Parameter param =
+          parameters.size() > pos ? parameters.get(pos) : null;
+      if (param != null) {
+        if (!firstParam) {
+          insertSql.append(",");
+          valueClause.append(", ");
+        }
+        insertSql.append("`").append(colInfo.getColumnName()).append("`");
+        valueClause.append("?");
+        firstParam = false;
+      } else {
+        if (Arrays.asList(primaryCols).contains(colInfo.getColumnName())) {
+          boolean isAutoIncrement =
+              colInfo.isAutoIncrement() || (primaryCols.length == 1 && isAutoincrementPk);
+          if (isAutoIncrement || colInfo.hasDefault()) {
+            if (!isAutoIncrement
+                && (!context.getVersion().isMariaDBServer()
+                    || !context.getVersion().versionGreaterOrEqual(10, 5, 1))) {
+              // driver cannot know generated default value like uuid().
+              // but for server 10.5+, will use RETURNING to know primary key
+              throw exceptionFactory.create(
+                  String.format(
+                      "Cannot call insertRow() not setting value for primary key %s "
+                          + "with default value before server 10.5",
+                      colInfo.getColumnName()));
+            }
+          } else {
+            throw exceptionFactory.create(
+                String.format(
+                    "Cannot call insertRow() not setting value for primary key %s",
+                    colInfo.getColumnName()));
+          }
+        } else if (!colInfo.hasDefault()) {
+          if (!firstParam) {
+            insertSql.append(",");
+            valueClause.append(", ");
+          }
+          firstParam = false;
+          insertSql.append("`").append(colInfo.getColumnName()).append("`");
+          valueClause.append("?");
+        }
+      }
+    }
+    insertSql.append(") VALUES (").append(valueClause).append(")");
+    if (context.getVersion().isMariaDBServer()
+        && context.getVersion().versionGreaterOrEqual(10, 5, 1)) {
+      insertSql.append(" RETURNING ").append(returningClause);
+    }
+    return insertSql.toString();
+  }
+
+  private String refreshStmt() {
+    // Construct SELECT query according to column metadata, with WHERE part containing primary
+    // fields
+    StringBuilder selectSql = new StringBuilder("SELECT ");
+    StringBuilder whereClause = new StringBuilder(" WHERE ");
+
+    boolean firstPrimary = true;
+    for (int pos = 0; pos < metadataList.length; pos++) {
+      Column colInfo = metadataList[pos];
+      if (pos != 0) {
+        selectSql.append(",");
+      }
+      selectSql.append("`").append(colInfo.getColumnName()).append("`");
+
+      if (Arrays.asList(primaryCols).contains(colInfo.getColumnName())) {
+        if (!firstPrimary) {
+          whereClause.append("AND ");
+        }
+        firstPrimary = false;
+        whereClause.append("`").append(colInfo.getColumnName()).append("` = ? ");
+      }
+    }
+    selectSql
+        .append(" FROM `")
+        .append(database)
+        .append("`.`")
+        .append(table)
+        .append("`")
+        .append(whereClause);
+    return selectSql.toString();
+  }
+
+  private PreparedStatement prepareRefreshStmt() throws SQLException {
+    // row's raw bytes must be encoded according to current resultSet type
+    // so use Server or Client PrepareStatement accordingly
+    return ((Connection) statement.getConnection())
+        .prepareInternal(
+            refreshStmt(),
+            Statement.RETURN_GENERATED_KEYS,
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_READ_ONLY,
+            rowDecoder instanceof BinaryRowDecoder);
+  }
+
+  private byte[] refreshRawData() throws SQLException {
+    int fieldsPrimaryIndex = 0;
+    try (PreparedStatement refreshPreparedStatement = prepareRefreshStmt()) {
+
+      for (int pos = 0; pos < metadataList.length; pos++) {
+        Column colInfo = metadataList[pos];
+        if (Arrays.asList(primaryCols).contains(colInfo.getColumnName())) {
+          if ((state != STATE_STANDARD) && parameters.size() > pos && parameters.get(pos) != null) {
+            // Row has just been updated using updateRow() methods.
+            // updateRow might have changed primary key, so must use the new value.
+            org.mariadb.jdbc.client.util.Parameter value = parameters.get(pos);
+            ((BasePreparedStatement) refreshPreparedStatement)
+                .setParameter(fieldsPrimaryIndex++, value);
+          } else {
+            refreshPreparedStatement.setObject(++fieldsPrimaryIndex, getObject(pos + 1));
+          }
+        }
+      }
+
+      Result rs = (Result) refreshPreparedStatement.executeQuery();
+      rs.next();
+      return rs.getCurrentRowData();
+    }
+  }
+
+  private String updateQuery() {
+    StringBuilder updateSql = new StringBuilder("UPDATE `" + database + "`.`" + table + "` SET ");
+    StringBuilder whereClause = new StringBuilder(" WHERE ");
+
+    boolean firstUpdate = true;
+
+    for (int pos = 0; pos < primaryCols.length; pos++) {
+      String key = primaryCols[pos];
+      if (pos != 0) {
+        whereClause.append("AND ");
+      }
+      whereClause.append("`").append(key).append("` = ? ");
+    }
+
+    for (int pos = 0; pos < metadataList.length; pos++) {
+      Column colInfo = metadataList[pos];
+
+      if (parameters.size() > pos && parameters.get(pos) != null) {
+        if (!firstUpdate) {
+          updateSql.append(",");
+        }
+        firstUpdate = false;
+        updateSql.append("`").append(colInfo.getColumnName()).append("` = ? ");
+      }
+    }
+    if (firstUpdate) return null;
+    return updateSql.append(whereClause).toString();
+  }
+
+  @Override
+  public void updateRow() throws SQLException {
+
+    if (state == STATE_INSERT) {
+      throw exceptionFactory.create("Cannot call updateRow() when inserting a new row");
+    }
+
+    if (rowPointer < 0) {
+      throw exceptionFactory.create("Current position is before the first row", "22023");
+    }
+
+    if (rowPointer >= dataSize) {
+      throw exceptionFactory.create("Current position is after the last row", "22023");
+    }
+
+    if (state == STATE_UPDATE || state == STATE_UPDATED) {
+
+      // state is STATE_UPDATE, meaning that at least one field is modified, update query can be
+      // run.
+      // Construct UPDATE query according to modified field only
+      String updateQuery = updateQuery();
+      if (updateQuery != null) {
+        try (PreparedStatement preparedStatement =
+            ((Connection) statement.getConnection())
+                .prepareInternal(
+                    updateQuery,
+                    Statement.RETURN_GENERATED_KEYS,
+                    ResultSet.TYPE_FORWARD_ONLY,
+                    ResultSet.CONCUR_READ_ONLY,
+                    rowDecoder instanceof BinaryRowDecoder)) {
+
+          int fieldsIndex = 0;
+          for (int pos = 0; pos < metadataList.length; pos++) {
+            if (parameters.size() > pos) {
+              org.mariadb.jdbc.client.util.Parameter param = parameters.get(pos);
+              if (param != null) {
+                ((BasePreparedStatement) preparedStatement).setParameter(fieldsIndex++, param);
+              }
+            }
+          }
+
+          for (int pos = 0; pos < metadataList.length; pos++) {
+            Column colInfo = metadataList[pos];
+            if (Arrays.asList(primaryCols).contains(colInfo.getColumnName())) {
+              preparedStatement.setObject(++fieldsIndex, getObject(pos + 1));
+            }
+          }
+
+          preparedStatement.execute();
+        }
+        refreshRow();
+      }
+      parameters = new ParameterList(parameters.size());
+      state = STATE_UPDATED;
+    }
+  }
+
+  @Override
+  public void deleteRow() throws SQLException {
+
+    if (state == STATE_INSERT) {
+      throw exceptionFactory.create("Cannot call deleteRow() when inserting a new row");
+    }
+    if (!canUpdate) {
+      throw exceptionFactory.create("ResultSet cannot be updated. " + changeError, sqlStateError);
+    }
+    if (rowPointer < 0) {
+      throw new SQLDataException("Current position is before the first row", "22023");
+    }
+    if (rowPointer >= dataSize) {
+      throw new SQLDataException("Current position is after the last row", "22023");
+    }
+
+    // Create query with WHERE clause contain primary field.
+    StringBuilder deleteSql =
+        new StringBuilder("DELETE FROM `" + database + "`.`" + table + "` WHERE ");
+    boolean firstPrimary = true;
+    for (Column colInfo : metadataList) {
+      if (Arrays.asList(primaryCols).contains(colInfo.getColumnName())) {
+        if (!firstPrimary) {
+          deleteSql.append("AND ");
+        }
+        firstPrimary = false;
+        deleteSql.append("`").append(colInfo.getColumnName()).append("` = ? ");
+      }
+    }
+
+    try (PreparedStatement deletePreparedStatement =
+        ((Connection) statement.getConnection())
+            .prepareInternal(
+                deleteSql.toString(),
+                Statement.RETURN_GENERATED_KEYS,
+                ResultSet.TYPE_FORWARD_ONLY,
+                ResultSet.CONCUR_READ_ONLY,
+                false)) {
+
+      int fieldsPrimaryIndex = 1;
+      for (int pos = 0; pos < metadataList.length; pos++) {
+        Column colInfo = metadataList[pos];
+        if (Arrays.asList(primaryCols).contains(colInfo.getColumnName())) {
+          deletePreparedStatement.setObject(fieldsPrimaryIndex++, getObject(pos + 1));
+        }
+      }
+
+      deletePreparedStatement.executeUpdate();
+
+      // remove data
+      System.arraycopy(data, rowPointer + 1, data, rowPointer, dataSize - 1 - rowPointer);
+      data[dataSize - 1] = null;
+      dataSize--;
+      previous();
+    }
+  }
+
+  @Override
+  public void refreshRow() throws SQLException {
+    if (state == STATE_INSERT) {
+      throw exceptionFactory.create("Cannot call refreshRow() when inserting a new row");
+    }
+    if (rowPointer < 0) {
+      throw exceptionFactory.create("Current position is before the first row", "22023");
+    }
+    if (rowPointer >= data.length) {
+      throw exceptionFactory.create("Current position is after the last row", "22023");
+    }
+    if (canUpdate) {
+      updateRowData(refreshRawData());
+    }
+  }
+
+  @Override
+  public void cancelRowUpdates() {
+    parameters = new ParameterList(parameters.size());
+    state = STATE_STANDARD;
+  }
+
+  @Override
+  public void moveToInsertRow() throws SQLException {
+    if (!canInsert) {
+      throw exceptionFactory.create("No row can be inserted. " + changeError, sqlStateError);
+    }
+    parameters = new ParameterList(parameters.size());
+    state = STATE_INSERT;
+    savedRowPointer = rowPointer;
+  }
+
+  @Override
+  public void moveToCurrentRow() {
+    state = STATE_STANDARD;
+    resetToRowPointer();
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, Blob x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(BlobCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, Blob x) throws SQLException {
+    updateBlob(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Clob x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ClobCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Clob x) throws SQLException {
+    updateClob(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateNString(int columnIndex, String nString) throws SQLException {
+    updateString(columnIndex, nString);
+  }
+
+  @Override
+  public void updateNString(String columnLabel, String nString) throws SQLException {
+    updateString(columnLabel, nString);
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
+    updateClob(columnIndex, nClob);
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
+    updateClob(columnLabel, nClob);
+  }
+
+  @Override
+  public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+    updateCharacterStream(columnIndex, x, length);
+  }
+
+  @Override
+  public void updateNCharacterStream(String columnLabel, Reader reader, long length)
+      throws SQLException {
+    updateCharacterStream(columnLabel, reader, length);
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, length));
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, length));
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, x, length));
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream x, long length)
+      throws SQLException {
+    updateAsciiStream(findColumn(columnLabel), x, length);
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream x, long length)
+      throws SQLException {
+    updateBinaryStream(findColumn(columnLabel), x, length);
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader, long length)
+      throws SQLException {
+    updateCharacterStream(findColumn(columnLabel), reader, length);
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, InputStream x, long length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, length));
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, InputStream inputStream, long length)
+      throws SQLException {
+    updateBlob(findColumn(columnLabel), inputStream, length);
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Reader x, long length) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, x, length));
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
+    updateClob(findColumn(columnLabel), reader, length);
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
+    updateClob(columnIndex, reader, length);
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
+    updateClob(columnLabel, reader, length);
+  }
+
+  @Override
+  public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
+    updateCharacterStream(columnIndex, x);
+  }
+
+  @Override
+  public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    updateCharacterStream(columnLabel, reader);
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
+    updateAsciiStream(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
+    updateBinaryStream(findColumn(columnLabel), x);
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    updateCharacterStream(findColumn(columnLabel), reader);
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, InputStream x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
+    updateBlob(findColumn(columnLabel), inputStream);
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Reader x) throws SQLException {
+    checkUpdatable(columnIndex);
+    parameters.set(columnIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, x));
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Reader reader) throws SQLException {
+    updateClob(findColumn(columnLabel), reader);
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+    updateClob(columnIndex, reader);
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, Reader reader) throws SQLException {
+    updateClob(columnLabel, reader);
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength)
+      throws SQLException {
+    updateInternalObject(columnIndex, x, (long) scaleOrLength);
+  }
+
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  private void updateInternalObject(int columnIndex, Object x, Long scaleOrLength)
+      throws SQLException {
+    checkUpdatable(columnIndex);
+    if (x == null) {
+      parameters.set(columnIndex - 1, Parameter.NULL_PARAMETER);
+      return;
+    }
+
+    for (Codec<?> codec : context.getConf().codecs()) {
+      if (codec.canEncode(x)) {
+        Parameter p = new Parameter(codec, x, scaleOrLength);
+        parameters.set(columnIndex - 1, p);
+        return;
+      }
+    }
+
+    throw new SQLException(String.format("Type %s not supported type", x.getClass().getName()));
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength)
+      throws SQLException {
+    updateObject(findColumn(columnLabel), x, targetSqlType, scaleOrLength);
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x, SQLType targetSqlType) throws SQLException {
+    updateInternalObject(columnIndex, x, null);
+  }
+
+  @Override
+  public void updateObject(String columnLabel, Object x, SQLType targetSqlType)
+      throws SQLException {
+    updateObject(findColumn(columnLabel), x, targetSqlType);
+  }
+
+  @Override
+  public int getConcurrency() {
+    return CONCUR_UPDATABLE;
+  }
+
+  private void resetToRowPointer() {
+    rowPointer = savedRowPointer;
+    if (rowPointer != BEFORE_FIRST_POS && rowPointer < dataSize - 1) {
+      setRow(data[rowPointer]);
+    } else {
+      // all data are reads and pointer is after last
+      setNullRowBuf();
+    }
+    savedRowPointer = -1;
+  }
+
+  @Override
+  public void beforeFirst() throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    super.beforeFirst();
+  }
+
+  @Override
+  public boolean first() throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    return super.first();
+  }
+
+  @Override
+  public boolean last() throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    return super.last();
+  }
+
+  @Override
+  public void afterLast() throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    super.afterLast();
+  }
+
+  @Override
+  public boolean absolute(int row) throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    return super.absolute(row);
+  }
+
+  @Override
+  public boolean relative(int rows) throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    return super.relative(rows);
+  }
+
+  @Override
+  public boolean next() throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    return super.next();
+  }
+
+  @Override
+  public boolean previous() throws SQLException {
+    if (state == STATE_INSERT) {
+      resetToRowPointer();
+    }
+    state = STATE_STANDARD;
+    return super.previous();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/BinaryRowDecoder.java b/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/BinaryRowDecoder.java
new file mode 100644
index 0000000..dffb6ff
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/BinaryRowDecoder.java
@@ -0,0 +1,261 @@
+package org.mariadb.jdbc.client.result.rowdecoder;
+
+import static org.mariadb.jdbc.client.result.Result.NULL_LENGTH;
+
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.util.MutableInt;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** BINARY rows decoder */
+public class BinaryRowDecoder implements RowDecoder {
+
+  /**
+   * Binary decode data according to data type.
+   *
+   * @param codec current codec
+   * @param cal calendar
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @param metadataList metadatas
+   * @param fieldIndex field index
+   * @return default object according to metadata
+   * @param <T> Codec default return type
+   * @throws SQLException if any decoding error occurs
+   */
+  public <T> T decode(
+      Codec<T> codec,
+      Calendar cal,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex)
+      throws SQLException {
+    return codec.decodeBinary(rowBuf, fieldLength, metadataList[fieldIndex.get()], cal);
+  }
+
+  @Override
+  public Object defaultDecode(
+      Configuration conf,
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].getDefaultBinary(conf, rowBuf, fieldLength);
+  }
+
+  public String decodeString(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeStringBinary(rowBuf, fieldLength, null);
+  }
+
+  public byte decodeByte(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeByteBinary(rowBuf, fieldLength);
+  }
+
+  public boolean decodeBoolean(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeBooleanBinary(rowBuf, fieldLength);
+  }
+
+  public Date decodeDate(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeDateBinary(rowBuf, fieldLength, cal);
+  }
+
+  public Time decodeTime(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeTimeBinary(rowBuf, fieldLength, cal);
+  }
+
+  public Timestamp decodeTimestamp(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeTimestampBinary(rowBuf, fieldLength, cal);
+  }
+
+  public short decodeShort(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeShortBinary(rowBuf, fieldLength);
+  }
+
+  public int decodeInt(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeIntBinary(rowBuf, fieldLength);
+  }
+
+  public long decodeLong(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeLongBinary(rowBuf, fieldLength);
+  }
+
+  public float decodeFloat(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeFloatBinary(rowBuf, fieldLength);
+  }
+
+  public double decodeDouble(
+      ColumnDecoder[] metadataList,
+      final MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeDoubleBinary(rowBuf, fieldLength);
+  }
+
+  public boolean wasNull(byte[] nullBitmap, final MutableInt fieldIndex, int fieldLength) {
+    return (nullBitmap[(fieldIndex.get() + 2) / 8] & (1 << ((fieldIndex.get() + 2) % 8))) > 0;
+  }
+
+  /**
+   * Set length and pos indicator to asked index.
+   *
+   * @param newIndex index (0 is first).
+   */
+  @Override
+  public int setPosition(
+      int newIndex,
+      final MutableInt fieldIndex,
+      int maxIndex,
+      StandardReadableByteBuf rowBuf,
+      byte[] nullBitmap,
+      ColumnDecoder[] metadataList) {
+
+    if (fieldIndex.get() >= newIndex) {
+      fieldIndex.set(0);
+      rowBuf.pos(1);
+      rowBuf.readBytes(nullBitmap);
+    } else {
+      fieldIndex.incrementAndGet();
+      if (fieldIndex.get() == 0) {
+        // skip header + null-bitmap
+        rowBuf.pos(1);
+        rowBuf.readBytes(nullBitmap);
+      }
+    }
+
+    while (fieldIndex.get() < newIndex) {
+      if ((nullBitmap[(fieldIndex.get() + 2) / 8] & (1 << ((fieldIndex.get() + 2) % 8))) == 0) {
+        // skip bytes
+        switch (metadataList[fieldIndex.get()].getType()) {
+          case BIGINT:
+          case DOUBLE:
+            rowBuf.skip(8);
+            break;
+
+          case INTEGER:
+          case MEDIUMINT:
+          case FLOAT:
+            rowBuf.skip(4);
+            break;
+
+          case SMALLINT:
+          case YEAR:
+            rowBuf.skip(2);
+            break;
+
+          case TINYINT:
+            rowBuf.skip(1);
+            break;
+
+          default:
+            rowBuf.skipLengthEncoded();
+            break;
+        }
+      }
+      fieldIndex.incrementAndGet();
+    }
+
+    if (wasNull(nullBitmap, fieldIndex, 0)) {
+      return NULL_LENGTH;
+    }
+
+    // read asked field position and length
+    switch (metadataList[fieldIndex.get()].getType()) {
+      case BIGINT:
+      case DOUBLE:
+        return 8;
+
+      case INTEGER:
+      case MEDIUMINT:
+      case FLOAT:
+        return 4;
+
+      case SMALLINT:
+      case YEAR:
+        return 2;
+
+      case TINYINT:
+        return 1;
+
+      default:
+        // field with variable length
+        byte len = rowBuf.readByte();
+        switch (len) {
+          case (byte) 252:
+            // length is encoded on 3 bytes (0xfc header + 2 bytes indicating length)
+            return rowBuf.readUnsignedShort();
+
+          case (byte) 253:
+            // length is encoded on 4 bytes (0xfd header + 3 bytes indicating length)
+            return rowBuf.readUnsignedMedium();
+
+          case (byte) 254:
+            // length is encoded on 9 bytes (0xfe header + 8 bytes indicating length)
+            return (int) rowBuf.readLong();
+          default:
+            return len & 0xff;
+        }
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/RowDecoder.java b/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/RowDecoder.java
new file mode 100644
index 0000000..ec173d8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/RowDecoder.java
@@ -0,0 +1,269 @@
+package org.mariadb.jdbc.client.result.rowdecoder;
+
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.util.MutableInt;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Row decoder interface */
+public interface RowDecoder {
+  /**
+   * Indicate if last decoded value was null
+   *
+   * @param nullBitmap null bitmap
+   * @param fieldIndex field index
+   * @param fieldLength field length
+   * @return true if last value was null
+   */
+  boolean wasNull(byte[] nullBitmap, MutableInt fieldIndex, int fieldLength);
+
+  /**
+   * Position the read index on buffer to data at indicated index.
+   *
+   * @param newIndex new data index
+   * @param fieldIndex current field index
+   * @param maxIndex maximum index
+   * @param rowBuf row buffer
+   * @param nullBitmap null bitmap
+   * @param metadataList metadata list
+   * @return new index to read data
+   */
+  int setPosition(
+      int newIndex,
+      MutableInt fieldIndex,
+      int maxIndex,
+      StandardReadableByteBuf rowBuf,
+      byte[] nullBitmap,
+      ColumnDecoder[] metadataList);
+
+  /**
+   * Decode data according to data type.
+   *
+   * @param codec current codec
+   * @param calendar calendar
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @param metadataList metadatas
+   * @param fieldIndex field index
+   * @return default object according to metadata
+   * @param <T> Codec default return type
+   * @throws SQLException if any decoding error occurs
+   */
+  <T> T decode(
+      Codec<T> codec,
+      Calendar calendar,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex)
+      throws SQLException;
+
+  /**
+   * Decode data according to data type.
+   *
+   * @param conf configuration
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if any decoding error occurs
+   */
+  Object defaultDecode(
+      Configuration conf,
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+
+  /**
+   * Decode data according to byte.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to byte value
+   */
+  byte decodeByte(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+
+  /**
+   * Decode data according to boolean.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to boolean value
+   */
+  boolean decodeBoolean(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+  /**
+   * Decode data according to Date.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @param cal calendar
+   * @return data
+   * @throws SQLException if data type cannot be decoded to Date value
+   */
+  Date decodeDate(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException;
+  /**
+   * Decode data according to Time.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @param cal calendar
+   * @return data
+   * @throws SQLException if data type cannot be decoded to Time value
+   */
+  Time decodeTime(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException;
+  /**
+   * Decode data according to Timestamp.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @param cal calendar
+   * @return data
+   * @throws SQLException if data type cannot be decoded to Timestamp value
+   */
+  Timestamp decodeTimestamp(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException;
+  /**
+   * Decode data according to short.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to short value
+   */
+  short decodeShort(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+  /**
+   * Decode data according to int.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to int value
+   */
+  int decodeInt(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+  /**
+   * Decode data according to String.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to String value
+   */
+  String decodeString(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+  /**
+   * Decode data according to long.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to long value
+   */
+  long decodeLong(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+  /**
+   * Decode data according to float.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to float value
+   */
+  float decodeFloat(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+  /**
+   * Decode data according to double.
+   *
+   * @param metadataList metadata list
+   * @param fieldIndex field index
+   * @param rowBuf row buffer
+   * @param fieldLength field length
+   * @return data
+   * @throws SQLException if data type cannot be decoded to double value
+   */
+  double decodeDouble(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException;
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/TextRowDecoder.java b/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/TextRowDecoder.java
new file mode 100644
index 0000000..5f08db3
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/result/rowdecoder/TextRowDecoder.java
@@ -0,0 +1,190 @@
+package org.mariadb.jdbc.client.result.rowdecoder;
+
+import static org.mariadb.jdbc.client.result.Result.NULL_LENGTH;
+
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.util.MutableInt;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** TEXT rows decoder */
+public class TextRowDecoder implements RowDecoder {
+
+  @Override
+  public <T> T decode(
+      Codec<T> codec,
+      Calendar cal,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex)
+      throws SQLException {
+    return codec.decodeText(rowBuf, fieldLength, metadataList[fieldIndex.get()], cal);
+  }
+
+  @Override
+  public Object defaultDecode(
+      Configuration conf,
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].getDefaultText(conf, rowBuf, fieldLength);
+  }
+
+  @Override
+  public String decodeString(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeStringText(rowBuf, fieldLength, null);
+  }
+
+  public byte decodeByte(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeByteText(rowBuf, fieldLength);
+  }
+
+  public boolean decodeBoolean(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeBooleanText(rowBuf, fieldLength);
+  }
+
+  public Date decodeDate(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeDateText(rowBuf, fieldLength, cal);
+  }
+
+  public Time decodeTime(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeTimeText(rowBuf, fieldLength, cal);
+  }
+
+  public Timestamp decodeTimestamp(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength,
+      Calendar cal)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeTimestampText(rowBuf, fieldLength, cal);
+  }
+
+  public short decodeShort(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeShortText(rowBuf, fieldLength);
+  }
+
+  public int decodeInt(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeIntText(rowBuf, fieldLength);
+  }
+
+  public long decodeLong(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeLongText(rowBuf, fieldLength);
+  }
+
+  public float decodeFloat(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeFloatText(rowBuf, fieldLength);
+  }
+
+  public double decodeDouble(
+      ColumnDecoder[] metadataList,
+      MutableInt fieldIndex,
+      StandardReadableByteBuf rowBuf,
+      int fieldLength)
+      throws SQLException {
+    return metadataList[fieldIndex.get()].decodeDoubleText(rowBuf, fieldLength);
+  }
+
+  public boolean wasNull(byte[] nullBitmap, MutableInt fieldIndex, int fieldLength) {
+    return fieldLength == NULL_LENGTH;
+  }
+
+  /**
+   * Set length and pos indicator to asked index.
+   *
+   * @param newIndex index (1 is first).
+   */
+  @Override
+  public int setPosition(
+      int newIndex,
+      final MutableInt fieldIndex,
+      final int maxIndex,
+      final StandardReadableByteBuf rowBuf,
+      final byte[] nullBitmap,
+      final ColumnDecoder[] metadataList) {
+    if (fieldIndex.get() >= newIndex) {
+      fieldIndex.set(0);
+      rowBuf.pos(0);
+    } else {
+      fieldIndex.incrementAndGet();
+    }
+
+    while (fieldIndex.get() < newIndex) {
+      rowBuf.skipLengthEncoded();
+      fieldIndex.incrementAndGet();
+    }
+
+    byte len = rowBuf.buf[rowBuf.pos++];
+    switch (len) {
+      case (byte) 251:
+        return NULL_LENGTH;
+      case (byte) 252:
+        return rowBuf.readUnsignedShort();
+      case (byte) 253:
+        return rowBuf.readUnsignedMedium();
+      case (byte) 254:
+        int fieldLength = (int) rowBuf.readUnsignedInt();
+        rowBuf.skip(4);
+        return fieldLength;
+      default:
+        return len & 0xff;
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/Reader.java b/src/main/java/org/mariadb/jdbc/client/socket/Reader.java
new file mode 100644
index 0000000..5dbf3f3
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/Reader.java
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket;
+
+import java.io.IOException;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.util.MutableByte;
+
+/** Packet Reader */
+public interface Reader {
+
+  /**
+   * Get next MySQL packet. Packet is expected to have size &lt; 16M and will use if possible an
+   * internal cached buffer. This packet bytes are expect to be read immediately
+   *
+   * @param traceEnable must trace pacjet
+   * @return Readable byte array packet.
+   * @throws IOException if socket exception occur.
+   */
+  ReadableByteBuf readReusablePacket(boolean traceEnable) throws IOException;
+
+  /**
+   * Get next MySQL packet. Packet is expected to have size &lt; 16M and will use if possible an
+   * internal cached buffer. This packet bytes are expect to be read immediately
+   *
+   * @return Readable byte array packet.
+   * @throws IOException if socket exception occur.
+   */
+  ReadableByteBuf readReusablePacket() throws IOException;
+
+  /**
+   * Get next MySQL packet. If packet is more than 16M, read as many packet needed to finish reading
+   * MySQL packet. (first that has not length = 16Mb)
+   *
+   * @param traceEnable must trace packet.
+   * @return array packet.
+   * @throws IOException if socket exception occur.
+   */
+  byte[] readPacket(boolean traceEnable) throws IOException;
+
+  /**
+   * Get a readable byte array from byte array. This packet is expected to be read immediately,
+   * since no lock is set on this packet.
+   *
+   * @param buf byte array to be parsed
+   * @return array packet.
+   */
+  ReadableByteBuf readableBufFromArray(byte[] buf);
+
+  /**
+   * Skip next MySQL packet. Packet is expected to have size &lt; 16M
+   *
+   * @throws IOException if socket exception occur.
+   */
+  void skipPacket() throws IOException;
+
+  /**
+   * Get current sequence object
+   *
+   * @return current sequence
+   */
+  MutableByte getSequence();
+
+  /**
+   * Close stream
+   *
+   * @throws IOException if any error occurs
+   */
+  void close() throws IOException;
+
+  /**
+   * Set server thread id.
+   *
+   * @param serverThreadId current server thread id.
+   * @param hostAddress host information
+   */
+  void setServerThreadId(Long serverThreadId, HostAddress hostAddress);
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/Writer.java b/src/main/java/org/mariadb/jdbc/client/socket/Writer.java
new file mode 100644
index 0000000..a9482e2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/Writer.java
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket;
+
+import java.io.IOException;
+import org.mariadb.jdbc.HostAddress;
+
+/** Packet Writer interface */
+public interface Writer {
+  /**
+   * current buffer position
+   *
+   * @return current buffer position
+   */
+  int pos();
+
+  /**
+   * Current buffer
+   *
+   * @return current buffer
+   */
+  byte[] buf();
+
+  /**
+   * Set current buffer position
+   *
+   * @param pos position
+   * @throws IOException if buffer cannot grow to position
+   */
+  void pos(int pos) throws IOException;
+
+  /**
+   * Write byte into buf, flush buf to socket if needed.
+   *
+   * @param value byte to send
+   * @throws IOException if socket error occur.
+   */
+  void writeByte(int value) throws IOException;
+
+  /**
+   * Write short value into buf. flush buf if too small.
+   *
+   * @param value short value
+   * @throws IOException if socket error occur
+   */
+  void writeShort(short value) throws IOException;
+
+  /**
+   * Write int value into buf. flush buf if too small.
+   *
+   * @param value int value
+   * @throws IOException if socket error occur
+   */
+  void writeInt(int value) throws IOException;
+
+  /**
+   * Write long value into buf. flush buf if too small.
+   *
+   * @param value long value
+   * @throws IOException if socket error occur
+   */
+  void writeLong(long value) throws IOException;
+
+  /**
+   * Write Double binary value to buffer
+   *
+   * @param value double value
+   * @throws IOException if socket error occur
+   */
+  void writeDouble(double value) throws IOException;
+
+  /**
+   * Write float binary value to buffer
+   *
+   * @param value float value
+   * @throws IOException if socket error occur
+   */
+  void writeFloat(float value) throws IOException;
+
+  /**
+   * Write byte array to buffer
+   *
+   * @param arr bytes
+   * @throws IOException if socket error occur
+   */
+  void writeBytes(byte[] arr) throws IOException;
+
+  /**
+   * Write byte array to buffer at a specific position
+   *
+   * @param arr bytes
+   * @param pos position
+   */
+  void writeBytesAtPos(byte[] arr, int pos);
+
+  /**
+   * Write byte array to buf. If buf is full, flush socket.
+   *
+   * @param arr byte array
+   * @param off offset
+   * @param len byte length to write
+   * @throws IOException if socket error occur
+   */
+  void writeBytes(byte[] arr, int off, int len) throws IOException;
+
+  /**
+   * Write field length into buf, flush socket if needed.
+   *
+   * @param length field length
+   * @throws IOException if socket error occur.
+   */
+  void writeLength(long length) throws IOException;
+
+  /**
+   * Write ascii string to buffer
+   *
+   * @param str string
+   * @throws IOException if socket error occurs
+   */
+  void writeAscii(String str) throws IOException;
+
+  /**
+   * Write utf8 string to buffer
+   *
+   * @param str string
+   * @throws IOException if socket error occurs
+   */
+  void writeString(String str) throws IOException;
+
+  /**
+   * Write string to socket.
+   *
+   * @param str string
+   * @param noBackslashEscapes escape method
+   * @throws IOException if socket error occur
+   */
+  void writeStringEscaped(String str, boolean noBackslashEscapes) throws IOException;
+
+  /**
+   * Write escape bytes to socket.
+   *
+   * @param bytes bytes
+   * @param len len to write
+   * @param noBackslashEscapes escape method
+   * @throws IOException if socket error occur
+   */
+  void writeBytesEscaped(byte[] bytes, int len, boolean noBackslashEscapes) throws IOException;
+
+  /**
+   * Send empty packet.
+   *
+   * @throws IOException if socket error occur.
+   */
+  void writeEmptyPacket() throws IOException;
+
+  /**
+   * Send packet to socket.
+   *
+   * @throws IOException if socket error occur.
+   */
+  void flush() throws IOException;
+
+  /**
+   * Send packet to buffered outputstream without flushing
+   *
+   * @throws IOException if socket error occur.
+   */
+  void flushPipeline() throws IOException;
+
+  /**
+   * must a max allowed length exception be thrown
+   *
+   * @param length command length
+   * @return true if too big
+   */
+  boolean throwMaxAllowedLength(int length);
+
+  /**
+   * Get current command length
+   *
+   * @return command length
+   */
+  long getCmdLength();
+
+  /**
+   * Indicate if logging trace are permitted
+   *
+   * @param permitTrace permits trace to be logged
+   */
+  void permitTrace(boolean permitTrace);
+
+  /**
+   * Set server thread id.
+   *
+   * @param serverThreadId current server thread id.
+   * @param hostAddress host information
+   */
+  void setServerThreadId(Long serverThreadId, HostAddress hostAddress);
+
+  /** mark position */
+  void mark();
+
+  /**
+   * has some position been marked
+   *
+   * @return is marked
+   */
+  boolean isMarked();
+
+  /**
+   * Current command has flushed packet to socket
+   *
+   * @return indicate if some packet have been flushed
+   */
+  boolean hasFlushed();
+
+  /**
+   * Flush to last mark.
+   *
+   * @throws IOException if flush fail.
+   */
+  void flushBufferStopAtMark() throws IOException;
+
+  /**
+   * Buffer has data after marked position
+   *
+   * @return indicate if there is data after marked position
+   */
+  boolean bufIsDataAfterMark();
+
+  /**
+   * Reset mark flag and send bytes after mark flag.
+   *
+   * @return bytes after mark flag
+   */
+  byte[] resetMark();
+
+  /** reset sequences and position for sending a new packet */
+  void initPacket();
+
+  /**
+   * Close socket stream
+   *
+   * @throws IOException if any error occurs
+   */
+  void close() throws IOException;
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/CompressInputStream.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/CompressInputStream.java
new file mode 100644
index 0000000..c716901
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/CompressInputStream.java
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
+import org.mariadb.jdbc.client.util.MutableByte;
+
+/**
+ * Compression handler, permitting decompression of mysql packet if needed. When compression is set,
+ * using a 7 byte header to identify is packet is compressed or not.
+ */
+public class CompressInputStream extends InputStream {
+  private final InputStream in;
+  private final MutableByte sequence;
+
+  private final byte[] header = new byte[7];
+
+  private int end;
+  private int pos;
+  private byte[] buf;
+
+  /**
+   * Constructor. When this handler is used, driver expect packet with 7 byte compression header
+   *
+   * @param in socket input stream
+   * @param compressionSequence compression sequence
+   */
+  public CompressInputStream(InputStream in, MutableByte compressionSequence) {
+    this.in = in;
+    this.sequence = compressionSequence;
+  }
+
+  /**
+   * Reads up to <code>len</code> bytes of data from the input stream into an array of bytes. An
+   * attempt is made to read as many as <code>len</code> bytes, but a smaller number may be read.
+   * The number of bytes actually read is returned as an integer.
+   *
+   * <p>This method blocks until input data is available, end of file is detected, or an exception
+   * is thrown.
+   *
+   * <p>If <code>len</code> is zero, then no bytes are read and <code>0</code> is returned;
+   * otherwise, there is an attempt to read at least one byte. If no byte is available because the
+   * stream is at end of file, the value <code>-1</code> is returned; otherwise, at least one byte
+   * is read and stored into <code>b</code>.
+   *
+   * <p>The first byte read is stored into element <code>b[off]</code>, the next one into <code>
+   * b[off+1]</code>, and so on. The number of bytes read is, at most, equal to <code>len</code>.
+   * Let <i>k</i> be the number of bytes actually read; these bytes will be stored in elements
+   * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>, leaving elements
+   * <code>b[off+</code><i>k</i><code>]</code> through <code>b[off+len-1]</code> unaffected.
+   *
+   * <p>In every case, elements <code>b[0]</code> through <code>b[off]</code> and elements <code>
+   * b[off+len]</code> through <code>b[b.length-1]</code> are unaffected.
+   *
+   * <p>The <code>read(b,</code> <code>off,</code> <code>len)</code> method for class <code>
+   * InputStream</code> simply calls the method <code>read()</code> repeatedly. If the first such
+   * call results in an <code>IOException</code>, that exception is returned from the call to the
+   * <code>read(b,</code> <code>off,</code> <code>len)</code> method. If any subsequent call to
+   * <code>read()</code> results in a <code>IOException</code>, the exception is caught and treated
+   * as if it were end of file; the bytes read up to that point are stored into <code>b</code> and
+   * the number of bytes read before the exception occurred is returned. The default implementation
+   * of this method blocks until the requested amount of input data <code>len</code> has been read,
+   * end of file is detected, or an exception is thrown. Subclasses are encouraged to provide a more
+   * efficient implementation of this method.
+   *
+   * @param b the buffer into which the data is read.
+   * @param off the start offset in array <code>b</code> at which the data is written.
+   * @param len the maximum number of bytes to read.
+   * @return the total number of bytes read into the buffer, or <code>-1</code> if there is no more
+   *     data because the end of the stream has been reached.
+   * @throws IOException If the first byte cannot be read for any reason other than end of file, or
+   *     if the input stream has been closed, or if some other I/O error occurs.
+   * @throws NullPointerException If <code>b</code> is <code>null</code>.
+   * @throws IndexOutOfBoundsException If <code>off</code> is negative, <code>len</code> is
+   *     negative, or <code>len</code> is greater than <code>b.length - off</code>
+   * @see InputStream#read()
+   */
+  @Override
+  public int read(byte[] b, int off, int len) throws IOException {
+    if (len == 0) {
+      return 0;
+    }
+
+    int totalReads = 0;
+
+    do {
+      if (end - pos <= 0) {
+        retrieveBuffer();
+      }
+      // copy internal value to buf.
+      int copyLength = Math.min(len - totalReads, end - pos);
+      System.arraycopy(buf, pos, b, off + totalReads, copyLength);
+      pos += copyLength;
+      totalReads += copyLength;
+    } while (totalReads < len && super.available() > 0);
+
+    return totalReads;
+  }
+
+  private void retrieveBuffer() throws IOException {
+    // ***************************************************
+    // Read header
+    // ***************************************************
+    int remaining = 7;
+    int readOffset = 0;
+    do {
+      int count = in.read(header, readOffset, remaining);
+      if (count < 0) {
+        throw new EOFException(
+            "unexpected end of stream, read "
+                + readOffset
+                + " bytes from 7 (socket was closed by server)");
+      }
+      remaining -= count;
+      readOffset += count;
+    } while (remaining > 0);
+
+    int compressedPacketLength =
+        (header[0] & 0xff) + ((header[1] & 0xff) << 8) + ((header[2] & 0xff) << 16);
+    sequence.set(header[3]);
+    int packetLength = (header[4] & 0xff) + ((header[5] & 0xff) << 8) + ((header[6] & 0xff) << 16);
+    boolean compressed = (packetLength != 0);
+    remaining = compressedPacketLength;
+    byte[] intermediaryBuf = new byte[remaining];
+
+    // ***************************************************
+    // Read content
+    // ***************************************************
+
+    readOffset = 0;
+    do {
+      int count = in.read(intermediaryBuf, readOffset, remaining);
+      if (count < 0) {
+        throw new EOFException(
+            "unexpected end of stream, read "
+                + ((compressed ? compressedPacketLength : packetLength) - remaining)
+                + " bytes from "
+                + (compressed ? compressedPacketLength : packetLength)
+                + " (socket was closed by server)");
+      }
+      remaining -= count;
+      readOffset += count;
+    } while (remaining > 0);
+
+    if (compressed) {
+      buf = new byte[packetLength];
+      Inflater inflater = new Inflater();
+      inflater.setInput(intermediaryBuf);
+      try {
+        int actualUncompressBytes = inflater.inflate(buf);
+        if (actualUncompressBytes != packetLength) {
+          throw new IOException(
+              "Invalid exception length after decompression "
+                  + actualUncompressBytes
+                  + ",expected "
+                  + packetLength);
+        }
+      } catch (DataFormatException dfe) {
+        throw new IOException(dfe);
+      }
+      inflater.end();
+      end = packetLength;
+    } else {
+      buf = intermediaryBuf;
+      end = compressedPacketLength;
+    }
+    pos = 0;
+  }
+
+  /**
+   * Skips over and discards <code>n</code> bytes of data from this input stream. The <code>skip
+   * </code> method may, for a variety of reasons, end up skipping over some smaller number of
+   * bytes, possibly <code>0</code>. This may result from any of a number of conditions; reaching
+   * end of file before <code>n</code> bytes have been skipped is only one possibility. The actual
+   * number of bytes skipped is returned. If {@code n} is negative, the {@code skip} method for
+   * class {@code InputStream} always returns 0, and no bytes are skipped. Subclasses may handle the
+   * negative value differently.
+   *
+   * <p>The <code>skip</code> method of this class creates a byte array and then repeatedly reads
+   * into it until <code>n</code> bytes have been read or the end of the stream has been reached.
+   * Subclasses are encouraged to provide a more efficient implementation of this method. For
+   * instance, the implementation may depend on the ability to seek.
+   *
+   * @param n the number of bytes to be skipped.
+   * @return the actual number of bytes skipped.
+   * @throws IOException if the stream does not support seek, or if some other I/O error occurs.
+   */
+  @Override
+  public long skip(long n) throws IOException {
+    return read(new byte[(int) n], 0, (int) n);
+  }
+
+  /**
+   * Returns an estimate of the number of bytes that can be read (or skipped over) from this input
+   * stream without blocking by the next invocation of a method for this input stream. The next
+   * invocation might be the same thread or another thread. A single read or skip of this many bytes
+   * will not block, but may read or skip fewer bytes.
+   *
+   * <p>Note that while some implementations of {@code InputStream} will return the total number of
+   * bytes in the stream, many will not. It is never correct to use the return value of this method
+   * to allocate a buffer intended to hold all data in this stream.
+   *
+   * <p>A subclass' implementation of this method may choose to throw an {@link IOException} if this
+   * input stream has been closed by invoking the {@link #close()} method.
+   *
+   * <p>The {@code available} method for class {@code InputStream} always returns {@code 0}.
+   *
+   * <p>This method should be overridden by subclasses.
+   *
+   * @return an estimate of the number of bytes that can be read (or skipped over) from this input
+   *     stream without blocking or {@code 0} when it reaches the end of the input stream.
+   * @throws IOException if an I/O error occurs.
+   */
+  @Override
+  public int available() throws IOException {
+    return in.available();
+  }
+
+  /**
+   * Closes this input stream and releases any system resources associated with the stream.
+   *
+   * <p>The <code>close</code> method of <code>InputStream</code> does nothing.
+   *
+   * @throws IOException if an I/O error occurs.
+   */
+  @Override
+  public void close() throws IOException {
+    in.close();
+  }
+
+  /**
+   * Marks the current position in this input stream. A subsequent call to the <code>reset</code>
+   * method repositions this stream at the last marked position so that subsequent reads re-read the
+   * same bytes.
+   *
+   * <p>The <code>readlimit</code> arguments tells this input stream to allow that many bytes to be
+   * read before the mark position gets invalidated.
+   *
+   * <p>The general contract of <code>mark</code> is that, if the method <code>markSupported</code>
+   * returns <code>true</code>, the stream somehow remembers all the bytes read after the call to
+   * <code>mark</code> and stands ready to supply those same bytes again if and whenever the method
+   * <code>reset</code> is called. However, the stream is not required to remember any data at all
+   * if more than <code>readlimit</code> bytes are read from the stream before <code>reset</code> is
+   * called.
+   *
+   * <p>Marking a closed stream should not have any effect on the stream.
+   *
+   * <p>The <code>mark</code> method of <code>InputStream</code> does nothing.
+   *
+   * @param readlimit the maximum limit of bytes that can be read before the mark position becomes
+   *     invalid.
+   * @see InputStream#reset()
+   */
+  @Override
+  public synchronized void mark(int readlimit) {
+    in.mark(readlimit);
+  }
+
+  /**
+   * Repositions this stream to the position at the time the <code>mark</code> method was last
+   * called on this input stream.
+   *
+   * <p>The general contract of <code>reset</code> is:
+   *
+   * <ul>
+   *   <li>If the method <code>markSupported</code> returns <code>true</code>, then:
+   *       <ul>
+   *         <li>If the method <code>mark</code> has not been called since the stream was created,
+   *             or the number of bytes read from the stream since <code>mark</code> was last called
+   *             is larger than the argument to <code>mark</code> at that last call, then an <code>
+   *             IOException</code> might be thrown.
+   *         <li>If such an <code>IOException</code> is not thrown, then the stream is reset to a
+   *             state such that all the bytes read since the most recent call to <code>mark</code>
+   *             (or since the start of the file, if <code>mark</code> has not been called) will be
+   *             resupplied to subsequent callers of the <code>read</code> method, followed by any
+   *             bytes that otherwise would have been the next input data as of the time of the call
+   *             to <code>reset</code>.
+   *       </ul>
+   *   <li>If the method <code>markSupported</code> returns <code>false</code>, then:
+   *       <ul>
+   *         <li>The call to <code>reset</code> may throw an <code>IOException</code>.
+   *         <li>If an <code>IOException</code> is not thrown, then the stream is reset to a fixed
+   *             state that depends on the particular type of the input stream and how it was
+   *             created. The bytes that will be supplied to subsequent callers of the <code>read
+   *             </code> method depend on the particular type of the input stream.
+   *       </ul>
+   * </ul>
+   *
+   * <p>The method <code>reset</code> for class <code>InputStream</code> does nothing except throw
+   * an <code>IOException</code>.
+   *
+   * @throws IOException if this stream has not been marked or if the mark has been invalidated.
+   * @see InputStream#mark(int)
+   * @see IOException
+   */
+  @Override
+  public synchronized void reset() throws IOException {
+    in.reset();
+  }
+
+  /**
+   * Tests if this input stream supports the <code>mark</code> and <code>reset</code> methods.
+   * Whether <code>mark</code> and <code>reset</code> are supported is an invariant property of a
+   * particular input stream instance. The <code>markSupported</code> method of <code>
+   * InputStream</code> returns <code>false</code>.
+   *
+   * @return <code>true</code> if this stream instance supports the mark and reset methods; <code>
+   *     false</code> otherwise.
+   * @see InputStream#mark(int)
+   * @see InputStream#reset()
+   */
+  @Override
+  public boolean markSupported() {
+    return in.markSupported();
+  }
+
+  /**
+   * Reads the next byte of data from the input stream. The value byte is returned as an <code>int
+   * </code> in the range <code>0</code> to <code>255</code>. If no byte is available because the
+   * end of the stream has been reached, the value <code>-1</code> is returned. This method blocks
+   * until input data is available, the end of the stream is detected, or an exception is thrown.
+   *
+   * <p>A subclass must provide an implementation of this method.
+   *
+   * @return the next byte of data, or <code>-1</code> if the end of the stream is reached.
+   * @throws IOException if an I/O error occurs.
+   */
+  @Override
+  public int read() throws IOException {
+    throw new IOException("NOT IMPLEMENTED !");
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/CompressOutputStream.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/CompressOutputStream.java
new file mode 100644
index 0000000..cd239c7
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/CompressOutputStream.java
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.DeflaterOutputStream;
+import org.mariadb.jdbc.client.util.MutableByte;
+
+/**
+ * Compression writer handler Permit to wrap standard packet to compressed packet ( 7 byte header).
+ * Driver will compress packet only if packet size is meaningful (1536 bytes) &gt; to one TCP
+ * packet.
+ */
+public class CompressOutputStream extends OutputStream {
+  private static final int MIN_COMPRESSION_SIZE = 1536; // TCP-IP single packet
+  private final OutputStream out;
+  private final MutableByte sequence;
+  private final byte[] header = new byte[7];
+  private byte[] longPacketBuffer = null;
+
+  /**
+   * Constructor.
+   *
+   * @param out socket output stream
+   * @param compressionSequence compression sequence
+   */
+  public CompressOutputStream(OutputStream out, MutableByte compressionSequence) {
+    this.out = out;
+    this.sequence = compressionSequence;
+  }
+
+  /**
+   * Writes <code>len</code> bytes from the specified byte array starting at offset <code>off</code>
+   * to this output stream. The general contract for <code>write(b, off, len)</code> is that some
+   * bytes in the array <code>b</code> are written to the output stream in order; element <code>
+   * b[off]</code> is the first byte written and <code>b[off+len-1]</code> is the last byte written
+   * by this operation.
+   *
+   * <p>The <code>write</code> method of <code>OutputStream</code> calls the write method of one
+   * argument on each of the bytes to be written out. Subclasses are encouraged to override this
+   * method and provide a more efficient implementation.
+   *
+   * <p>If <code>b</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.
+   *
+   * <p>If <code>off</code> is negative, or <code>len</code> is negative, or <code>off+len</code> is
+   * greater than the length of the array <code>b</code>, then an IndexOutOfBoundsException is
+   * thrown.
+   *
+   * @param b the data.
+   * @param off the start offset in the data.
+   * @param len the number of bytes to write.
+   * @throws IOException if an I/O error occurs. In particular, an <code>IOException</code> is
+   *     thrown if the output stream is closed.
+   */
+  @Override
+  public void write(byte[] b, int off, int len) throws IOException {
+    if (len + ((longPacketBuffer != null) ? longPacketBuffer.length : 0) < MIN_COMPRESSION_SIZE) {
+      // *******************************************************************************
+      // small packet, no compression
+      // *******************************************************************************
+
+      if (longPacketBuffer != null) {
+        header[0] = (byte) (len + longPacketBuffer.length);
+        header[1] = (byte) ((len + longPacketBuffer.length) >>> 8);
+        header[2] = 0;
+        header[3] = sequence.incrementAndGet();
+        header[4] = 0;
+        header[5] = 0;
+        header[6] = 0;
+        out.write(header, 0, 7);
+        out.write(longPacketBuffer, 0, longPacketBuffer.length);
+        out.write(b, off, len);
+        longPacketBuffer = null;
+        return;
+      }
+
+      header[0] = (byte) len;
+      header[1] = (byte) (len >>> 8);
+      header[2] = 0;
+      header[3] = sequence.incrementAndGet();
+      header[4] = 0;
+      header[5] = 0;
+      header[6] = 0;
+      out.write(header, 0, 7);
+      out.write(b, off, len);
+
+    } else {
+      // *******************************************************************************
+      // compressing packet
+      // *******************************************************************************
+      int sent = 0;
+      try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+        try (DeflaterOutputStream deflater = new DeflaterOutputStream(baos)) {
+
+          /**
+           * For multi packet, len will be 0x00ffffff + 4 bytes for header. but compression can only
+           * compress up to 0x00ffffff bytes (header initial length size cannot be > 3 bytes) so,
+           * for this specific case, a buffer will save remaining data
+           */
+          if (longPacketBuffer != null) {
+            deflater.write(longPacketBuffer, 0, longPacketBuffer.length);
+            sent = longPacketBuffer.length;
+            longPacketBuffer = null;
+          }
+          if (len + sent > 0x00ffffff) {
+            int remaining = len + sent - 0x00ffffff;
+            longPacketBuffer = new byte[remaining];
+            System.arraycopy(b, off + 0x00ffffff - sent, longPacketBuffer, 0, remaining);
+          }
+
+          int bufLenSent = Math.min(0x00ffffff - sent, len);
+          deflater.write(b, off, bufLenSent);
+          sent += bufLenSent;
+          deflater.finish();
+        }
+
+        byte[] compressedBytes = baos.toByteArray();
+
+        int compressLen = compressedBytes.length;
+
+        header[0] = (byte) compressLen;
+        header[1] = (byte) (compressLen >>> 8);
+        header[2] = (byte) (compressLen >>> 16);
+        header[3] = sequence.incrementAndGet();
+        header[4] = (byte) sent;
+        header[5] = (byte) (sent >>> 8);
+        header[6] = (byte) (sent >>> 16);
+
+        out.write(header, 0, 7);
+        out.write(compressedBytes, 0, compressLen);
+        out.flush();
+      }
+    }
+  }
+
+  /**
+   * Flushes this output stream and forces any buffered output bytes to be written out. The general
+   * contract of <code>flush</code> is that calling it is an indication that, if any bytes
+   * previously written have been buffered by the implementation of the output stream, such bytes
+   * should immediately be written to their intended destination.
+   *
+   * <p>If the intended destination of this stream is an abstraction provided by the underlying
+   * operating system, for example a file, then flushing the stream guarantees only that bytes
+   * previously written to the stream are passed to the operating system for writing; it does not
+   * guarantee that they are actually written to a physical device such as a disk drive.
+   *
+   * <p>The <code>flush</code> method of <code>OutputStream</code> does nothing.
+   *
+   * @throws IOException if an I/O error occurs.
+   */
+  @Override
+  public void flush() throws IOException {
+    if (longPacketBuffer != null) {
+      byte[] b = longPacketBuffer;
+      longPacketBuffer = null;
+      write(b, 0, b.length);
+    }
+    out.flush();
+    sequence.set((byte) -1);
+  }
+
+  /**
+   * Closes this output stream and releases any system resources associated with this stream. The
+   * general contract of <code>close</code> is that it closes the output stream. A closed stream
+   * cannot perform output operations and cannot be reopened.
+   *
+   * <p>The <code>close</code> method of <code>OutputStream</code> does nothing.
+   *
+   * @throws IOException if an I/O error occurs.
+   */
+  @Override
+  public void close() throws IOException {
+    out.close();
+  }
+
+  /**
+   * Writes the specified byte to this output stream. The general contract for <code>write</code> is
+   * that one byte is written to the output stream. The byte to be written is the eight low-order
+   * bits of the argument <code>b</code>. The 24 high-order bits of <code>b</code> are ignored.
+   *
+   * <p>Subclasses of <code>OutputStream</code> must provide an implementation for this method.
+   *
+   * @param b the <code>byte</code>.
+   * @throws IOException if an I/O error occurs. In particular, an <code>IOException</code> may be
+   *     thrown if the output stream has been closed.
+   */
+  @Override
+  public void write(int b) throws IOException {
+    throw new IOException("NOT EXPECTED !");
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/NamedPipeSocket.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/NamedPipeSocket.java
new file mode 100644
index 0000000..4c8fd55
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/NamedPipeSocket.java
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import com.sun.jna.platform.win32.Kernel32;
+import java.io.*;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.concurrent.TimeUnit;
+
+/** Windows named pipe socket implementation */
+@SuppressWarnings("UnnecessaryInitCause")
+public class NamedPipeSocket extends Socket {
+
+  private final String host;
+  private final String name;
+
+  private RandomAccessFile file;
+  private InputStream is;
+  private OutputStream os;
+
+  /**
+   * Constructor
+   *
+   * @param host host
+   * @param name pipe name
+   */
+  public NamedPipeSocket(String host, String name) {
+    this.host = host;
+    this.name = name;
+  }
+
+  @Override
+  public void close() throws IOException {
+    if (file != null) {
+      file.close();
+      file = null;
+    }
+  }
+
+  /**
+   * Name pipe connection.
+   *
+   * @param endpoint endPoint
+   * @param timeout timeout in milliseconds
+   * @throws IOException exception
+   */
+  public void connect(SocketAddress endpoint, int timeout) throws IOException {
+    String filename =
+        String.format(
+            "\\\\%s\\pipe\\%s", (host == null || host.equals("localhost")) ? "." : host, name);
+
+    // use a default timeout of 100ms if no timeout set.
+    int usedTimeout = timeout == 0 ? 100 : timeout;
+    long initialNano = System.nanoTime();
+    do {
+      try {
+        file = new RandomAccessFile(filename, "rw");
+        break;
+      } catch (FileNotFoundException fileNotFoundException) {
+        try {
+          // using JNA if available
+          Kernel32.INSTANCE.WaitNamedPipe(filename, timeout);
+          // then retry connection
+          file = new RandomAccessFile(filename, "rw");
+        } catch (Throwable cle) {
+          // in case JNA not on classpath, then wait 10ms before next try.
+          if (System.nanoTime() - initialNano > TimeUnit.MILLISECONDS.toNanos(usedTimeout)) {
+            if (timeout == 0) {
+              throw new FileNotFoundException(
+                  fileNotFoundException.getMessage()
+                      + "\n"
+                      + "please consider set connectTimeout option, so connection can retry having"
+                      + " access to named pipe. \n"
+                      + "(Named pipe can throw ERROR_PIPE_BUSY error)");
+            }
+            throw fileNotFoundException;
+          }
+          try {
+            TimeUnit.MILLISECONDS.sleep(5);
+          } catch (InterruptedException interrupted) {
+            IOException ioException =
+                new IOException("Interruption during connection to named pipe");
+            ioException.initCause(interrupted);
+            throw ioException;
+          }
+        }
+      }
+    } while (true);
+
+    is =
+        new InputStream() {
+          @Override
+          public int read(byte[] bytes, int off, int len) throws IOException {
+            return file.read(bytes, off, len);
+          }
+
+          @Override
+          public int read() throws IOException {
+            return file.read();
+          }
+
+          @Override
+          public int read(byte[] bytes) throws IOException {
+            return file.read(bytes);
+          }
+        };
+
+    os =
+        new OutputStream() {
+          @Override
+          public void write(byte[] bytes, int off, int len) throws IOException {
+            file.write(bytes, off, len);
+          }
+
+          @Override
+          public void write(int value) {}
+        };
+  }
+
+  public InputStream getInputStream() {
+    return is;
+  }
+
+  public OutputStream getOutputStream() {
+    return os;
+  }
+
+  public void setTcpNoDelay(boolean bool) {
+    // do nothing
+  }
+
+  public void setKeepAlive(boolean bool) {
+    // do nothing
+  }
+
+  public void setSoLinger(boolean bool, int value) {
+    // do nothing
+  }
+
+  @Override
+  public void setSoTimeout(int timeout) {
+    // do nothing
+  }
+
+  public void shutdownOutput() {
+    // do nothing
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/PacketReader.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/PacketReader.java
new file mode 100644
index 0000000..26c09f1
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/PacketReader.java
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.util.MutableByte;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.LoggerHelper;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Packet reader */
+public class PacketReader implements Reader {
+
+  private StandardReadableByteBuf readBuf = new StandardReadableByteBuf(null, 0);
+
+  private static final int REUSABLE_BUFFER_LENGTH = 1024;
+  private static final int MAX_PACKET_SIZE = 0xffffff;
+  private static final Logger logger = Loggers.getLogger(PacketReader.class);
+
+  private final byte[] header = new byte[4];
+  private final byte[] reusableArray = new byte[REUSABLE_BUFFER_LENGTH];
+  private final InputStream inputStream;
+  private final int maxQuerySizeToLog;
+
+  private final MutableByte sequence;
+  private String serverThreadLog = "";
+
+  /**
+   * Constructor of standard socket MySQL packet stream reader.
+   *
+   * @param in stream
+   * @param conf connection options
+   * @param sequence current increment sequence
+   */
+  public PacketReader(InputStream in, Configuration conf, MutableByte sequence) {
+    this.inputStream = in;
+    this.maxQuerySizeToLog = conf.maxQuerySizeToLog();
+    this.sequence = sequence;
+  }
+
+  public ReadableByteBuf readableBufFromArray(byte[] buf) {
+    readBuf.buf(buf, buf.length, 0);
+    return readBuf;
+  }
+
+  public ReadableByteBuf readReusablePacket() throws IOException {
+    return readReusablePacket(logger.isTraceEnabled());
+  }
+
+  public ReadableByteBuf readReusablePacket(boolean traceEnable) throws IOException {
+    // ***************************************************
+    // Read 4 byte header
+    // ***************************************************
+    int remaining = 4;
+    int off = 0;
+    do {
+      int count = inputStream.read(header, off, remaining);
+      if (count < 0) {
+        throw new EOFException(
+            "unexpected end of stream, read "
+                + off
+                + " bytes from 4 (socket was closed by server)");
+      }
+      remaining -= count;
+      off += count;
+    } while (remaining > 0);
+
+    int lastPacketLength =
+        (header[0] & 0xff) + ((header[1] & 0xff) << 8) + ((header[2] & 0xff) << 16);
+    sequence.set(header[3]);
+
+    // prepare array
+    byte[] rawBytes;
+    if (lastPacketLength < REUSABLE_BUFFER_LENGTH) {
+      rawBytes = reusableArray;
+    } else {
+      rawBytes = new byte[lastPacketLength];
+    }
+
+    // ***************************************************
+    // Read content
+    // ***************************************************
+    remaining = lastPacketLength;
+    off = 0;
+    do {
+      int count = inputStream.read(rawBytes, off, remaining);
+      if (count < 0) {
+        throw new EOFException(
+            "unexpected end of stream, read "
+                + (lastPacketLength - remaining)
+                + " bytes from "
+                + lastPacketLength
+                + " (socket was closed by server)");
+      }
+      remaining -= count;
+      off += count;
+    } while (remaining > 0);
+
+    if (traceEnable) {
+      logger.trace(
+          "read: {}\n{}",
+          serverThreadLog,
+          LoggerHelper.hex(header, rawBytes, 0, lastPacketLength, maxQuerySizeToLog));
+    }
+
+    readBuf.buf(rawBytes, lastPacketLength, 0);
+    return readBuf;
+  }
+
+  /**
+   * Get next MySQL packet. If packet is more than 16M, read as many packet needed to finish reading
+   * MySQL packet. (first that has not length = 16Mb)
+   *
+   * @param traceEnable must trace packet.
+   * @return array packet.
+   * @throws IOException if socket exception occur.
+   */
+  public byte[] readPacket(boolean traceEnable) throws IOException {
+    // ***************************************************
+    // Read 4 byte header
+    // ***************************************************
+    int remaining = 4;
+    int off = 0;
+    do {
+      int count = inputStream.read(header, off, remaining);
+      if (count < 0) {
+        throw new EOFException(
+            "unexpected end of stream, read "
+                + off
+                + " bytes from 4 (socket was closed by server)");
+      }
+      remaining -= count;
+      off += count;
+    } while (remaining > 0);
+
+    int lastPacketLength =
+        (header[0] & 0xff) + ((header[1] & 0xff) << 8) + ((header[2] & 0xff) << 16);
+
+    // prepare array
+    byte[] rawBytes = new byte[lastPacketLength];
+
+    // ***************************************************
+    // Read content
+    // ***************************************************
+    remaining = lastPacketLength;
+    off = 0;
+    do {
+      int count = inputStream.read(rawBytes, off, remaining);
+      if (count < 0) {
+        throw new EOFException(
+            "unexpected end of stream, read "
+                + (lastPacketLength - remaining)
+                + " bytes from "
+                + lastPacketLength
+                + " (socket was closed by server)");
+      }
+      remaining -= count;
+      off += count;
+    } while (remaining > 0);
+
+    if (traceEnable) {
+      logger.trace(
+          "read: {}\n{}",
+          serverThreadLog,
+          LoggerHelper.hex(header, rawBytes, 0, lastPacketLength, maxQuerySizeToLog));
+    }
+
+    // ***************************************************
+    // In case content length is big, content will be separate in many 16Mb packets
+    // ***************************************************
+    if (lastPacketLength == MAX_PACKET_SIZE) {
+      int packetLength;
+      do {
+        remaining = 4;
+        off = 0;
+        do {
+          int count = inputStream.read(header, off, remaining);
+          if (count < 0) {
+            throw new EOFException("unexpected end of stream, read " + off + " bytes from 4");
+          }
+          remaining -= count;
+          off += count;
+        } while (remaining > 0);
+
+        packetLength = (header[0] & 0xff) + ((header[1] & 0xff) << 8) + ((header[2] & 0xff) << 16);
+
+        int currentbufLength = rawBytes.length;
+        byte[] newRawBytes = new byte[currentbufLength + packetLength];
+        System.arraycopy(rawBytes, 0, newRawBytes, 0, currentbufLength);
+        rawBytes = newRawBytes;
+
+        // ***************************************************
+        // Read content
+        // ***************************************************
+        remaining = packetLength;
+        off = currentbufLength;
+        do {
+          int count = inputStream.read(rawBytes, off, remaining);
+          if (count < 0) {
+            throw new EOFException(
+                "unexpected end of stream, read "
+                    + (packetLength - remaining)
+                    + " bytes from "
+                    + packetLength);
+          }
+          remaining -= count;
+          off += count;
+        } while (remaining > 0);
+
+        if (traceEnable) {
+          logger.trace(
+              "read: {}\n{}",
+              serverThreadLog,
+              LoggerHelper.hex(
+                  header, rawBytes, currentbufLength, packetLength, maxQuerySizeToLog));
+        }
+
+        lastPacketLength += packetLength;
+      } while (packetLength == MAX_PACKET_SIZE);
+    }
+
+    return rawBytes;
+  }
+
+  public void skipPacket() throws IOException {
+    if (logger.isTraceEnabled()) {
+      readReusablePacket(logger.isTraceEnabled());
+      return;
+    }
+
+    // ***************************************************
+    // Read 4 byte header
+    // ***************************************************
+    int remaining = 4;
+    int off = 0;
+    do {
+      int count = inputStream.read(header, off, remaining);
+      if (count < 0) {
+        throw new EOFException(
+            "unexpected end of stream, read "
+                + off
+                + " bytes from 4 (socket was closed by server)");
+      }
+      remaining -= count;
+      off += count;
+    } while (remaining > 0);
+
+    int lastPacketLength =
+        (header[0] & 0xff) + ((header[1] & 0xff) << 8) + ((header[2] & 0xff) << 16);
+
+    remaining = lastPacketLength;
+    do {
+      remaining -= inputStream.skip(remaining);
+    } while (remaining > 0);
+
+    // ***************************************************
+    // In case content length is big, content will be separate in many 16Mb packets
+    // ***************************************************
+    if (lastPacketLength == MAX_PACKET_SIZE) {
+      int packetLength;
+      do {
+        remaining = 4;
+        off = 0;
+        do {
+          int count = inputStream.read(header, off, remaining);
+          if (count < 0) {
+            throw new EOFException("unexpected end of stream, read " + off + " bytes from 4");
+          }
+          remaining -= count;
+          off += count;
+        } while (remaining > 0);
+
+        packetLength = (header[0] & 0xff) + ((header[1] & 0xff) << 8) + ((header[2] & 0xff) << 16);
+
+        remaining = packetLength;
+        do {
+          remaining -= inputStream.skip(remaining);
+        } while (remaining > 0);
+
+        lastPacketLength += packetLength;
+      } while (packetLength == MAX_PACKET_SIZE);
+    }
+  }
+
+  public MutableByte getSequence() {
+    return sequence;
+  }
+
+  public void close() throws IOException {
+    inputStream.close();
+  }
+
+  /**
+   * Set server thread id.
+   *
+   * @param serverThreadId current server thread id.
+   * @param hostAddress host information
+   */
+  public void setServerThreadId(Long serverThreadId, HostAddress hostAddress) {
+    Boolean isMaster = hostAddress != null ? hostAddress.primary : null;
+    this.serverThreadLog =
+        "conn="
+            + (serverThreadId == null ? "-1" : serverThreadId)
+            + ((isMaster != null) ? " (" + (isMaster ? "M" : "S") + ")" : "");
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/PacketWriter.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/PacketWriter.java
new file mode 100644
index 0000000..7504cc2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/PacketWriter.java
@@ -0,0 +1,882 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.util.MutableByte;
+import org.mariadb.jdbc.export.MaxAllowedPacketException;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.LoggerHelper;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Packet writer */
+@SuppressWarnings("SameReturnValue")
+public class PacketWriter implements Writer {
+
+  /** initial buffer size */
+  public static final int SMALL_BUFFER_SIZE = 8192;
+
+  private static final Logger logger = Loggers.getLogger(PacketWriter.class);
+  private static final byte QUOTE = (byte) '\'';
+  private static final byte DBL_QUOTE = (byte) '"';
+  private static final byte ZERO_BYTE = (byte) '\0';
+  private static final byte BACKSLASH = (byte) '\\';
+  private static final int MEDIUM_BUFFER_SIZE = 128 * 1024;
+  private static final int LARGE_BUFFER_SIZE = 1024 * 1024;
+  private static final int MAX_PACKET_LENGTH = 0x00ffffff + 4;
+  private final int maxQuerySizeToLog;
+  private final OutputStream out;
+  private int maxPacketLength = MAX_PACKET_LENGTH;
+  private Integer maxAllowedPacket;
+  private long cmdLength;
+  private boolean permitTrace = true;
+  private String serverThreadLog = "";
+  private int mark = -1;
+  private boolean bufContainDataAfterMark = false;
+
+  /** internal buffer */
+  protected byte[] buf;
+  /** buffer position */
+  protected int pos = 4;
+  /** packet sequence */
+  protected final MutableByte sequence;
+  /** compressed packet sequence */
+  protected final MutableByte compressSequence;
+
+  /**
+   * Common feature to write data into socket, creating MariaDB Packet.
+   *
+   * @param out output stream
+   * @param maxQuerySizeToLog maximum query size to log
+   * @param maxAllowedPacket max allowed packet value if known
+   * @param sequence packet sequence
+   * @param compressSequence compressed packet sequence
+   */
+  public PacketWriter(
+      OutputStream out,
+      int maxQuerySizeToLog,
+      Integer maxAllowedPacket,
+      MutableByte sequence,
+      MutableByte compressSequence) {
+    this.out = out;
+    this.buf = new byte[SMALL_BUFFER_SIZE];
+    this.maxQuerySizeToLog = maxQuerySizeToLog;
+    this.cmdLength = 0;
+    this.sequence = sequence;
+    this.compressSequence = compressSequence;
+    this.maxAllowedPacket = maxAllowedPacket;
+  }
+
+  /**
+   * get current position
+   *
+   * @return current position
+   */
+  public int pos() {
+    return pos;
+  }
+
+  /**
+   * position setter
+   *
+   * @param pos new position
+   * @throws IOException if buffer is not big enough to contains new position
+   */
+  public void pos(int pos) throws IOException {
+    if (pos > buf.length) growBuffer(pos);
+    this.pos = pos;
+  }
+
+  /**
+   * get current command length
+   *
+   * @return current command length
+   */
+  public long getCmdLength() {
+    return cmdLength;
+  }
+
+  /**
+   * Write byte into buf, flush buf to socket if needed.
+   *
+   * @param value byte to send
+   * @throws IOException if socket error occur.
+   */
+  public void writeByte(int value) throws IOException {
+    if (pos >= buf.length) {
+      if (pos >= maxPacketLength && !bufContainDataAfterMark) {
+        // buf is more than a Packet, must flushbuf()
+        writeSocket(false);
+      } else {
+        growBuffer(1);
+      }
+    }
+    buf[pos++] = (byte) value;
+  }
+
+  /**
+   * Write short value into buf. flush buf if too small.
+   *
+   * @param value short value
+   * @throws IOException if socket error occur
+   */
+  public void writeShort(short value) throws IOException {
+    if (2 > buf.length - pos) {
+      // not enough space remaining
+      writeBytes(new byte[] {(byte) value, (byte) (value >> 8)}, 0, 2);
+      return;
+    }
+
+    buf[pos] = (byte) value;
+    buf[pos + 1] = (byte) (value >> 8);
+    pos += 2;
+  }
+
+  /**
+   * Write int value into buf. flush buf if too small.
+   *
+   * @param value int value
+   * @throws IOException if socket error occur
+   */
+  public void writeInt(int value) throws IOException {
+    if (4 > buf.length - pos) {
+      // not enough space remaining
+      byte[] arr = new byte[4];
+      arr[0] = (byte) value;
+      arr[1] = (byte) (value >> 8);
+      arr[2] = (byte) (value >> 16);
+      arr[3] = (byte) (value >> 24);
+      writeBytes(arr, 0, 4);
+      return;
+    }
+
+    buf[pos] = (byte) value;
+    buf[pos + 1] = (byte) (value >> 8);
+    buf[pos + 2] = (byte) (value >> 16);
+    buf[pos + 3] = (byte) (value >> 24);
+    pos += 4;
+  }
+
+  /**
+   * Write long value into buf. flush buf if too small.
+   *
+   * @param value long value
+   * @throws IOException if socket error occur
+   */
+  public void writeLong(long value) throws IOException {
+    if (8 > buf.length - pos) {
+      // not enough space remaining
+      byte[] arr = new byte[8];
+      arr[0] = (byte) value;
+      arr[1] = (byte) (value >> 8);
+      arr[2] = (byte) (value >> 16);
+      arr[3] = (byte) (value >> 24);
+      arr[4] = (byte) (value >> 32);
+      arr[5] = (byte) (value >> 40);
+      arr[6] = (byte) (value >> 48);
+      arr[7] = (byte) (value >> 56);
+      writeBytes(arr, 0, 8);
+      return;
+    }
+
+    buf[pos] = (byte) value;
+    buf[pos + 1] = (byte) (value >> 8);
+    buf[pos + 2] = (byte) (value >> 16);
+    buf[pos + 3] = (byte) (value >> 24);
+    buf[pos + 4] = (byte) (value >> 32);
+    buf[pos + 5] = (byte) (value >> 40);
+    buf[pos + 6] = (byte) (value >> 48);
+    buf[pos + 7] = (byte) (value >> 56);
+    pos += 8;
+  }
+
+  public void writeDouble(double value) throws IOException {
+    writeLong(Double.doubleToLongBits(value));
+  }
+
+  public void writeFloat(float value) throws IOException {
+    writeInt(Float.floatToIntBits(value));
+  }
+
+  public void writeBytes(byte[] arr) throws IOException {
+    writeBytes(arr, 0, arr.length);
+  }
+
+  public void writeBytesAtPos(byte[] arr, int pos) {
+    System.arraycopy(arr, 0, buf, pos, arr.length);
+  }
+
+  /**
+   * Write byte array to buf. If buf is full, flush socket.
+   *
+   * @param arr byte array
+   * @param off offset
+   * @param len byte length to write
+   * @throws IOException if socket error occur
+   */
+  public void writeBytes(byte[] arr, int off, int len) throws IOException {
+    if (len > buf.length - pos) {
+      if (buf.length != maxPacketLength) {
+        growBuffer(len);
+      }
+
+      // max buf size
+      if (len > buf.length - pos) {
+
+        if (mark != -1) {
+          growBuffer(len);
+          if (mark != -1) {
+            flushBufferStopAtMark();
+          }
+        }
+
+        if (len > buf.length - pos) {
+          // not enough space in buf, will stream :
+          // fill buf and flush until all data are snd
+          int remainingLen = len;
+          do {
+            int lenToFillbuf = Math.min(maxPacketLength - pos, remainingLen);
+            System.arraycopy(arr, off, buf, pos, lenToFillbuf);
+            remainingLen -= lenToFillbuf;
+            off += lenToFillbuf;
+            pos += lenToFillbuf;
+            if (remainingLen > 0) {
+              writeSocket(false);
+            } else {
+              break;
+            }
+          } while (true);
+          return;
+        }
+      }
+    }
+
+    System.arraycopy(arr, off, buf, pos, len);
+    pos += len;
+  }
+
+  /**
+   * Write field length into buf, flush socket if needed.
+   *
+   * @param length field length
+   * @throws IOException if socket error occur.
+   */
+  public void writeLength(long length) throws IOException {
+    if (length < 251) {
+      writeByte((byte) length);
+      return;
+    }
+
+    if (length < 65536) {
+
+      if (3 > buf.length - pos) {
+        // not enough space remaining
+        byte[] arr = new byte[3];
+        arr[0] = (byte) 0xfc;
+        arr[1] = (byte) length;
+        arr[2] = (byte) (length >>> 8);
+        writeBytes(arr, 0, 3);
+        return;
+      }
+
+      buf[pos] = (byte) 0xfc;
+      buf[pos + 1] = (byte) length;
+      buf[pos + 2] = (byte) (length >>> 8);
+      pos += 3;
+      return;
+    }
+
+    if (length < 16777216) {
+
+      if (4 > buf.length - pos) {
+        // not enough space remaining
+        byte[] arr = new byte[4];
+        arr[0] = (byte) 0xfd;
+        arr[1] = (byte) length;
+        arr[2] = (byte) (length >>> 8);
+        arr[3] = (byte) (length >>> 16);
+        writeBytes(arr, 0, 4);
+        return;
+      }
+
+      buf[pos] = (byte) 0xfd;
+      buf[pos + 1] = (byte) length;
+      buf[pos + 2] = (byte) (length >>> 8);
+      buf[pos + 3] = (byte) (length >>> 16);
+      pos += 4;
+      return;
+    }
+
+    if (9 > buf.length - pos) {
+      // not enough space remaining
+      byte[] arr = new byte[9];
+      arr[0] = (byte) 0xfe;
+      arr[1] = (byte) length;
+      arr[2] = (byte) (length >>> 8);
+      arr[3] = (byte) (length >>> 16);
+      arr[4] = (byte) (length >>> 24);
+      arr[5] = (byte) (length >>> 32);
+      arr[6] = (byte) (length >>> 40);
+      arr[7] = (byte) (length >>> 48);
+      arr[8] = (byte) (length >>> 56);
+      writeBytes(arr, 0, 9);
+      return;
+    }
+
+    buf[pos] = (byte) 0xfe;
+    buf[pos + 1] = (byte) length;
+    buf[pos + 2] = (byte) (length >>> 8);
+    buf[pos + 3] = (byte) (length >>> 16);
+    buf[pos + 4] = (byte) (length >>> 24);
+    buf[pos + 5] = (byte) (length >>> 32);
+    buf[pos + 6] = (byte) (length >>> 40);
+    buf[pos + 7] = (byte) (length >>> 48);
+    buf[pos + 8] = (byte) (length >>> 56);
+    pos += 9;
+  }
+
+  public void writeAscii(String str) throws IOException {
+    int len = str.length();
+    if (len > buf.length - pos) {
+      byte[] arr = str.getBytes(StandardCharsets.US_ASCII);
+      writeBytes(arr, 0, arr.length);
+      return;
+    }
+    for (int off = 0; off < len; ) {
+      this.buf[this.pos++] = (byte) str.charAt(off++);
+    }
+  }
+
+  public void writeString(String str) throws IOException {
+    int charsLength = str.length();
+
+    // not enough space remaining
+    if (charsLength * 3 >= buf.length - pos) {
+      byte[] arr = str.getBytes(StandardCharsets.UTF_8);
+      writeBytes(arr, 0, arr.length);
+      return;
+    }
+
+    // create UTF-8 byte array
+    // since java char are internally using UTF-16 using surrogate's pattern, 4 bytes unicode
+    // characters will
+    // represent 2 characters : example "\uD83C\uDFA4" = 🎤 unicode 8 "no microphones"
+    // so max size is 3 * charLength
+    // (escape characters are 1 byte encoded, so length might only be 2 when escape)
+    // + 2 for the quotes for text protocol
+    int charsOffset = 0;
+    char currChar;
+
+    // quick loop if only ASCII chars for faster escape
+    for (;
+        charsOffset < charsLength && (currChar = str.charAt(charsOffset)) < 0x80;
+        charsOffset++) {
+      buf[pos++] = (byte) currChar;
+    }
+
+    // if quick loop not finished
+    while (charsOffset < charsLength) {
+      currChar = str.charAt(charsOffset++);
+      if (currChar < 0x80) {
+        buf[pos++] = (byte) currChar;
+      } else if (currChar < 0x800) {
+        buf[pos++] = (byte) (0xc0 | (currChar >> 6));
+        buf[pos++] = (byte) (0x80 | (currChar & 0x3f));
+      } else if (currChar >= 0xD800 && currChar < 0xE000) {
+        // reserved for surrogate - see https://en.wikipedia.org/wiki/UTF-16
+        if (currChar < 0xDC00) {
+          // is high surrogate
+          if (charsOffset + 1 > charsLength) {
+            buf[pos++] = (byte) 0x63;
+          } else {
+            char nextChar = str.charAt(charsOffset);
+            if (nextChar >= 0xDC00 && nextChar < 0xE000) {
+              // is low surrogate
+              int surrogatePairs =
+                  ((currChar << 10) + nextChar) + (0x010000 - (0xD800 << 10) - 0xDC00);
+              buf[pos++] = (byte) (0xf0 | ((surrogatePairs >> 18)));
+              buf[pos++] = (byte) (0x80 | ((surrogatePairs >> 12) & 0x3f));
+              buf[pos++] = (byte) (0x80 | ((surrogatePairs >> 6) & 0x3f));
+              buf[pos++] = (byte) (0x80 | (surrogatePairs & 0x3f));
+              charsOffset++;
+            } else {
+              // must have low surrogate
+              buf[pos++] = (byte) 0x3f;
+            }
+          }
+        } else {
+          // low surrogate without high surrogate before
+          buf[pos++] = (byte) 0x3f;
+        }
+      } else {
+        buf[pos++] = (byte) (0xe0 | ((currChar >> 12)));
+        buf[pos++] = (byte) (0x80 | ((currChar >> 6) & 0x3f));
+        buf[pos++] = (byte) (0x80 | (currChar & 0x3f));
+      }
+    }
+  }
+
+  /**
+   * Current buffer
+   *
+   * @return current buffer
+   */
+  public byte[] buf() {
+    return buf;
+  }
+
+  /**
+   * Write string to socket.
+   *
+   * @param str string
+   * @param noBackslashEscapes escape method
+   * @throws IOException if socket error occur
+   */
+  public void writeStringEscaped(String str, boolean noBackslashEscapes) throws IOException {
+
+    int charsLength = str.length();
+
+    // not enough space remaining
+    if (charsLength * 3 >= buf.length - pos) {
+      byte[] arr = str.getBytes(StandardCharsets.UTF_8);
+      writeBytesEscaped(arr, arr.length, noBackslashEscapes);
+      return;
+    }
+
+    // create UTF-8 byte array
+    // since java char are internally using UTF-16 using surrogate's pattern, 4 bytes unicode
+    // characters will
+    // represent 2 characters : example "\uD83C\uDFA4" = 🎤 unicode 8 "no microphones"
+    // so max size is 3 * charLength
+    // (escape characters are 1 byte encoded, so length might only be 2 when escape)
+    // + 2 for the quotes for text protocol
+    int charsOffset = 0;
+    char currChar;
+
+    // quick loop if only ASCII chars for faster escape
+    if (noBackslashEscapes) {
+      for (;
+          charsOffset < charsLength && (currChar = str.charAt(charsOffset)) < 0x80;
+          charsOffset++) {
+        if (currChar == QUOTE) {
+          buf[pos++] = QUOTE;
+        }
+        buf[pos++] = (byte) currChar;
+      }
+    } else {
+      for (;
+          charsOffset < charsLength && (currChar = str.charAt(charsOffset)) < 0x80;
+          charsOffset++) {
+        if (currChar == BACKSLASH || currChar == QUOTE || currChar == 0 || currChar == DBL_QUOTE) {
+          buf[pos++] = BACKSLASH;
+        }
+        buf[pos++] = (byte) currChar;
+      }
+    }
+
+    // if quick loop not finished
+    while (charsOffset < charsLength) {
+      currChar = str.charAt(charsOffset++);
+      if (currChar < 0x80) {
+        if (noBackslashEscapes) {
+          if (currChar == QUOTE) {
+            buf[pos++] = QUOTE;
+          }
+        } else if (currChar == BACKSLASH
+            || currChar == QUOTE
+            || currChar == ZERO_BYTE
+            || currChar == DBL_QUOTE) {
+          buf[pos++] = BACKSLASH;
+        }
+        buf[pos++] = (byte) currChar;
+      } else if (currChar < 0x800) {
+        buf[pos++] = (byte) (0xc0 | (currChar >> 6));
+        buf[pos++] = (byte) (0x80 | (currChar & 0x3f));
+      } else if (currChar >= 0xD800 && currChar < 0xE000) {
+        // reserved for surrogate - see https://en.wikipedia.org/wiki/UTF-16
+        if (currChar < 0xDC00) {
+          // is high surrogate
+          if (charsOffset + 1 > charsLength) {
+            buf[pos++] = (byte) 0x63;
+          } else {
+            char nextChar = str.charAt(charsOffset);
+            if (nextChar >= 0xDC00 && nextChar < 0xE000) {
+              // is low surrogate
+              int surrogatePairs =
+                  ((currChar << 10) + nextChar) + (0x010000 - (0xD800 << 10) - 0xDC00);
+              buf[pos++] = (byte) (0xf0 | ((surrogatePairs >> 18)));
+              buf[pos++] = (byte) (0x80 | ((surrogatePairs >> 12) & 0x3f));
+              buf[pos++] = (byte) (0x80 | ((surrogatePairs >> 6) & 0x3f));
+              buf[pos++] = (byte) (0x80 | (surrogatePairs & 0x3f));
+              charsOffset++;
+            } else {
+              // must have low surrogate
+              buf[pos++] = (byte) 0x3f;
+            }
+          }
+        } else {
+          // low surrogate without high surrogate before
+          buf[pos++] = (byte) 0x3f;
+        }
+      } else {
+        buf[pos++] = (byte) (0xe0 | ((currChar >> 12)));
+        buf[pos++] = (byte) (0x80 | ((currChar >> 6) & 0x3f));
+        buf[pos++] = (byte) (0x80 | (currChar & 0x3f));
+      }
+    }
+  }
+
+  /**
+   * Write escape bytes to socket.
+   *
+   * @param bytes bytes
+   * @param len len to write
+   * @param noBackslashEscapes escape method
+   * @throws IOException if socket error occur
+   */
+  public void writeBytesEscaped(byte[] bytes, int len, boolean noBackslashEscapes)
+      throws IOException {
+    if (len * 2 > buf.length - pos) {
+
+      // makes buf bigger (up to 16M)
+      if (buf.length != maxPacketLength) {
+        growBuffer(len * 2);
+      }
+
+      // data may be bigger than buf.
+      // must flush buf when full (and reset position to 0)
+      if (len * 2 > buf.length - pos) {
+
+        if (mark != -1) {
+          growBuffer(len * 2);
+          if (mark != -1) {
+            flushBufferStopAtMark();
+          }
+
+        } else {
+          // not enough space in buf, will fill buf
+          if (buf.length <= pos) {
+            writeSocket(false);
+          }
+          if (noBackslashEscapes) {
+            for (int i = 0; i < len; i++) {
+              if (QUOTE == bytes[i]) {
+                buf[pos++] = QUOTE;
+                if (buf.length <= pos) {
+                  writeSocket(false);
+                }
+              }
+              buf[pos++] = bytes[i];
+              if (buf.length <= pos) {
+                writeSocket(false);
+              }
+            }
+          } else {
+            for (int i = 0; i < len; i++) {
+              if (bytes[i] == QUOTE
+                  || bytes[i] == BACKSLASH
+                  || bytes[i] == DBL_QUOTE
+                  || bytes[i] == ZERO_BYTE) {
+                buf[pos++] = '\\';
+                if (buf.length <= pos) {
+                  writeSocket(false);
+                }
+              }
+              buf[pos++] = bytes[i];
+              if (buf.length <= pos) {
+                writeSocket(false);
+              }
+            }
+          }
+          return;
+        }
+      }
+    }
+
+    // sure to have enough place filling buf directly
+    if (noBackslashEscapes) {
+      for (int i = 0; i < len; i++) {
+        if (QUOTE == bytes[i]) {
+          buf[pos++] = QUOTE;
+        }
+        buf[pos++] = bytes[i];
+      }
+    } else {
+      for (int i = 0; i < len; i++) {
+        if (bytes[i] == QUOTE
+            || bytes[i] == BACKSLASH
+            || bytes[i] == '"'
+            || bytes[i] == ZERO_BYTE) {
+          buf[pos++] = BACKSLASH; // add escape slash
+        }
+        buf[pos++] = bytes[i];
+      }
+    }
+  }
+
+  /**
+   * buf growing use 4 size only to avoid creating/copying that are expensive operations. possible
+   * size
+   *
+   * <ol>
+   *   <li>SMALL_buf_SIZE = 8k (default)
+   *   <li>MEDIUM_buf_SIZE = 128k
+   *   <li>LARGE_buf_SIZE = 1M
+   *   <li>getMaxPacketLength = 16M (+ 4 if using no compression)
+   * </ol>
+   *
+   * @param len length to add
+   */
+  private void growBuffer(int len) throws IOException {
+    int bufLength = buf.length;
+    int newCapacity;
+    if (bufLength == SMALL_BUFFER_SIZE) {
+      if (len + pos <= MEDIUM_BUFFER_SIZE) {
+        newCapacity = MEDIUM_BUFFER_SIZE;
+      } else if (len + pos <= LARGE_BUFFER_SIZE) {
+        newCapacity = LARGE_BUFFER_SIZE;
+      } else {
+        newCapacity = maxPacketLength;
+      }
+    } else if (bufLength == MEDIUM_BUFFER_SIZE) {
+      if (len + pos < LARGE_BUFFER_SIZE) {
+        newCapacity = LARGE_BUFFER_SIZE;
+      } else {
+        newCapacity = maxPacketLength;
+      }
+    } else if (bufContainDataAfterMark) {
+      // want to add some information to buf without having the command Header
+      // must grow buf until having all the query
+      newCapacity = Math.max(len + pos, maxPacketLength);
+    } else {
+      newCapacity = maxPacketLength;
+    }
+
+    if (len + pos > newCapacity) {
+      if (mark != -1) {
+        // buf is > 16M with mark.
+        // flush until mark, reset pos at beginning
+        flushBufferStopAtMark();
+
+        if (len + pos <= bufLength) {
+          return;
+        }
+
+        // need to keep all data, buf can grow more than maxPacketLength
+        // grow buf if needed
+        if (bufLength == maxPacketLength) return;
+        if (len + pos > newCapacity) {
+          newCapacity = Math.min(maxPacketLength, len + pos);
+        }
+      }
+    }
+
+    byte[] newBuf = new byte[newCapacity];
+    System.arraycopy(buf, 0, newBuf, 0, pos);
+    buf = newBuf;
+  }
+
+  /**
+   * Send empty packet.
+   *
+   * @throws IOException if socket error occur.
+   */
+  public void writeEmptyPacket() throws IOException {
+
+    buf[0] = (byte) 0x00;
+    buf[1] = (byte) 0x00;
+    buf[2] = (byte) 0x00;
+    buf[3] = this.sequence.incrementAndGet();
+    out.write(buf, 0, 4);
+
+    if (logger.isTraceEnabled()) {
+      logger.trace(
+          "send com : content length=0 {}\n{}", serverThreadLog, LoggerHelper.hex(buf, 0, 4));
+    }
+    out.flush();
+    cmdLength = 0;
+  }
+
+  /**
+   * Send packet to socket.
+   *
+   * @throws IOException if socket error occur.
+   */
+  public void flush() throws IOException {
+    writeSocket(true);
+
+    // if buf is big, and last query doesn't use at least half of it, resize buf to default
+    // value
+    if (buf.length > SMALL_BUFFER_SIZE && cmdLength * 2 < buf.length) {
+      buf = new byte[SMALL_BUFFER_SIZE];
+    }
+
+    pos = 4;
+    cmdLength = 0;
+    mark = -1;
+  }
+
+  public void flushPipeline() throws IOException {
+    writeSocket(false);
+
+    // if buf is big, and last query doesn't use at least half of it, resize buf to default
+    // value
+    if (buf.length > SMALL_BUFFER_SIZE && cmdLength * 2 < buf.length) {
+      buf = new byte[SMALL_BUFFER_SIZE];
+    }
+
+    pos = 4;
+    cmdLength = 0;
+    mark = -1;
+  }
+
+  /**
+   * Count query size. If query size is greater than max_allowed_packet and nothing has been already
+   * send, throw an exception to avoid having the connection closed.
+   *
+   * @param length additional length to query size
+   * @throws MaxAllowedPacketException if query has not to be sent.
+   */
+  private void checkMaxAllowedLength(int length) throws MaxAllowedPacketException {
+    if (maxAllowedPacket != null) {
+      if (cmdLength + length >= maxAllowedPacket) {
+        // launch exception only if no packet has been sent.
+        throw new MaxAllowedPacketException(
+            "query size ("
+                + (cmdLength + length)
+                + ") is >= to max_allowed_packet ("
+                + maxAllowedPacket
+                + ")",
+            cmdLength != 0);
+      }
+    }
+  }
+
+  public boolean throwMaxAllowedLength(int length) {
+    if (maxAllowedPacket != null) return cmdLength + length >= maxAllowedPacket;
+    return false;
+  }
+
+  public void permitTrace(boolean permitTrace) {
+    this.permitTrace = permitTrace;
+  }
+
+  /**
+   * Set server thread id.
+   *
+   * @param serverThreadId current server thread id.
+   * @param hostAddress host information
+   */
+  public void setServerThreadId(Long serverThreadId, HostAddress hostAddress) {
+    Boolean isMaster = hostAddress != null ? hostAddress.primary : null;
+    this.serverThreadLog =
+        "conn="
+            + (serverThreadId == null ? "-1" : serverThreadId)
+            + ((isMaster != null) ? " (" + (isMaster ? "M" : "S") + ")" : "");
+  }
+
+  public void mark() {
+    mark = pos;
+  }
+
+  public boolean isMarked() {
+    return mark != -1;
+  }
+
+  public boolean hasFlushed() {
+    return sequence.get() != -1;
+  }
+
+  /**
+   * Flush to last mark.
+   *
+   * @throws IOException if flush fail.
+   */
+  public void flushBufferStopAtMark() throws IOException {
+    final int end = pos;
+    pos = mark;
+    writeSocket(true);
+    out.flush();
+    initPacket();
+
+    System.arraycopy(buf, mark, buf, pos, end - mark);
+    pos += end - mark;
+    mark = -1;
+    bufContainDataAfterMark = true;
+  }
+
+  public boolean bufIsDataAfterMark() {
+    return bufContainDataAfterMark;
+  }
+
+  /**
+   * Reset mark flag and send bytes after mark flag.
+   *
+   * @return bytes after mark flag
+   */
+  public byte[] resetMark() {
+    pos = mark;
+    mark = -1;
+
+    if (bufContainDataAfterMark) {
+      byte[] data = Arrays.copyOfRange(buf, 4, pos);
+      initPacket();
+      bufContainDataAfterMark = false;
+      return data;
+    }
+    return null;
+  }
+
+  public void initPacket() {
+    sequence.set((byte) -1);
+    compressSequence.set((byte) -1);
+    pos = 4;
+    cmdLength = 0;
+  }
+
+  /**
+   * Flush the internal buf.
+   *
+   * @param commandEnd command end
+   * @throws IOException id connection error occur.
+   */
+  protected void writeSocket(boolean commandEnd) throws IOException {
+    if (pos > 4) {
+      buf[0] = (byte) (pos - 4);
+      buf[1] = (byte) ((pos - 4) >>> 8);
+      buf[2] = (byte) ((pos - 4) >>> 16);
+      buf[3] = this.sequence.incrementAndGet();
+      checkMaxAllowedLength(pos - 4);
+      out.write(buf, 0, pos);
+      if (commandEnd) out.flush();
+      cmdLength += pos - 4;
+
+      if (logger.isTraceEnabled()) {
+        if (permitTrace) {
+          logger.trace(
+              "send: {}\n{}", serverThreadLog, LoggerHelper.hex(buf, 0, pos, maxQuerySizeToLog));
+        } else {
+          logger.trace("send: content length={} {} com=<hidden>", pos - 4, serverThreadLog);
+        }
+      }
+
+      // if last com fill the max size, must send an empty com to indicate command end.
+      if (commandEnd && pos == maxPacketLength) {
+        writeEmptyPacket();
+      }
+
+      pos = 4;
+    }
+  }
+
+  public void close() throws IOException {
+    out.close();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/ReadAheadBufferedStream.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/ReadAheadBufferedStream.java
new file mode 100644
index 0000000..83c9fb4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/ReadAheadBufferedStream.java
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Permit to buf socket data, reading not only asked bytes, but available number of bytes when
+ * possible.
+ */
+public class ReadAheadBufferedStream extends FilterInputStream {
+
+  private static final int BUF_SIZE = 16384;
+  private final byte[] buf;
+  private int end;
+  private int pos;
+
+  /**
+   * Constructor
+   *
+   * @param in socket input stream
+   */
+  public ReadAheadBufferedStream(InputStream in) {
+    super(in);
+    buf = new byte[BUF_SIZE];
+    end = 0;
+    pos = 0;
+  }
+
+  /**
+   * Returning byte array, from cache of reading socket if needed.
+   *
+   * @param externalBuf buf to fill
+   * @param off offset
+   * @param len length to read
+   * @return number of added bytes
+   * @throws IOException if exception during socket reading
+   */
+  public synchronized int read(byte[] externalBuf, int off, int len) throws IOException {
+
+    if (len == 0) {
+      return 0;
+    }
+
+    int totalReads = 0;
+    while (true) {
+
+      // read
+      if (end - pos <= 0) {
+        if (len - totalReads >= buf.length) {
+          // buf length is less than asked byte and buf is empty
+          // => filling directly into external buf
+          int reads = super.read(externalBuf, off + totalReads, len - totalReads);
+          if (reads <= 0) {
+            return (totalReads == 0) ? -1 : totalReads;
+          }
+          return totalReads + reads;
+
+        } else {
+
+          // filling internal buf
+          fillingBuffer(len - totalReads);
+          if (end <= 0) {
+            return (totalReads == 0) ? -1 : totalReads;
+          }
+        }
+      }
+
+      // copy internal value to buf.
+      int copyLength = Math.min(len - totalReads, end - pos);
+      System.arraycopy(buf, pos, externalBuf, off + totalReads, copyLength);
+      pos += copyLength;
+      totalReads += copyLength;
+
+      if (totalReads >= len || super.available() <= 0) {
+        return totalReads;
+      }
+    }
+  }
+
+  /**
+   * Fill buf with required length, or available bytes.
+   *
+   * @param minNeededBytes asked number of bytes
+   * @throws IOException in case of failing reading stream.
+   */
+  private void fillingBuffer(int minNeededBytes) throws IOException {
+    int lengthToReallyRead = Math.min(BUF_SIZE, Math.max(super.available(), minNeededBytes));
+    end = super.read(buf, 0, lengthToReallyRead);
+    pos = 0;
+  }
+
+  public boolean markSupported() {
+    return false;
+  }
+
+  public void close() throws IOException {
+    super.close();
+    end = 0;
+    pos = 0;
+  }
+
+  public synchronized int available() throws IOException {
+    return end - pos + super.available();
+  }
+
+  public int read() throws IOException {
+    throw new IOException("read() from socket not implemented");
+  }
+
+  public long skip(long n) throws IOException {
+    throw new IOException("Skip from socket not implemented");
+  }
+
+  public void reset() throws IOException {
+    throw new IOException("reset from socket not implemented");
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/SocketHandlerFunction.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/SocketHandlerFunction.java
new file mode 100644
index 0000000..33d8d51
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/SocketHandlerFunction.java
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.sql.SQLException;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+
+/** Construct socket depending on configuration helper */
+@FunctionalInterface
+public interface SocketHandlerFunction {
+  /**
+   * Create socket
+   *
+   * @param conf configuration
+   * @param hostAddress host
+   * @return socket
+   * @throws IOException if any socket issue occurs
+   * @throws SQLException for other kind of error
+   */
+  Socket apply(Configuration conf, HostAddress hostAddress) throws IOException, SQLException;
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/SocketUtility.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/SocketUtility.java
new file mode 100644
index 0000000..b1b3d25
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/SocketUtility.java
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import com.sun.jna.Platform;
+import java.io.IOException;
+import org.mariadb.jdbc.client.impl.ConnectionHelper;
+
+/**
+ * Socket Utility, to defined function that will create socket according to dependency and
+ * configuration
+ */
+public class SocketUtility {
+
+  /**
+   * Create socket according to options. In case of compilation ahead of time, will throw an error
+   * if dependencies found, then use default socket implementation.
+   *
+   * @return Socket
+   */
+  @SuppressWarnings("unchecked")
+  public static SocketHandlerFunction getSocketHandler() {
+    // forcing use of JNA to ensure AOT compilation
+    Platform.getOSType();
+
+    return (conf, hostAddress) -> {
+      if (conf.pipe() != null) {
+        return new NamedPipeSocket(hostAddress != null ? hostAddress.host : null, conf.pipe());
+      } else if (conf.localSocket() != null) {
+        try {
+          return new UnixDomainSocket(conf.localSocket());
+        } catch (RuntimeException re) {
+          throw new IOException(re.getMessage(), re.getCause());
+        }
+      } else {
+        return ConnectionHelper.standardSocket(conf, hostAddress);
+      }
+    };
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/socket/impl/UnixDomainSocket.java b/src/main/java/org/mariadb/jdbc/client/socket/impl/UnixDomainSocket.java
new file mode 100644
index 0000000..1898894
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/socket/impl/UnixDomainSocket.java
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.socket.impl;
+
+import com.sun.jna.LastErrorException;
+import com.sun.jna.Native;
+import com.sun.jna.Platform;
+import com.sun.jna.Structure;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** Unix IPC socket */
+public class UnixDomainSocket extends Socket {
+
+  private static final int AF_UNIX = 1;
+  private static final int SOCK_STREAM = 1;
+  private static final int PROTOCOL = 0;
+
+  static {
+    if (!Platform.isWindows() && !Platform.isWindowsCE()) {
+      Native.register("c");
+    }
+  }
+
+  private final AtomicBoolean closeLock = new AtomicBoolean();
+  private final SockAddr sockaddr;
+  private final int fd;
+  private InputStream is;
+  private OutputStream os;
+  private boolean connected;
+
+  /**
+   * Constructor
+   *
+   * @param path unix path
+   * @throws IOException if any error occurs
+   */
+  public UnixDomainSocket(String path) throws IOException {
+    if (Platform.isWindows()) {
+      throw new IOException("Unix domain sockets are not supported on Windows");
+    }
+    sockaddr = new SockAddr(path);
+    closeLock.set(false);
+    try {
+      fd = socket(AF_UNIX, SOCK_STREAM, PROTOCOL);
+    } catch (LastErrorException lee) {
+      throw new IOException("native socket() failed : " + formatError(lee));
+    }
+  }
+
+  /**
+   * creates an endpoint for communication and returns a file descriptor that refers to that
+   * endpoint. see https://man7.org/linux/man-pages/man2/socket.2.html
+   *
+   * @param domain domain
+   * @param type type
+   * @param protocol protocol
+   * @return file descriptor
+   * @throws LastErrorException if any error occurs
+   */
+  public static native int socket(int domain, int type, int protocol) throws LastErrorException;
+
+  /**
+   * Connect socket
+   *
+   * @param sockfd file descriptor
+   * @param sockaddr socket address
+   * @param addrlen address length
+   * @return zero on success. -1 on error
+   * @throws LastErrorException if error occurs
+   */
+  public static native int connect(int sockfd, SockAddr sockaddr, int addrlen)
+      throws LastErrorException;
+
+  /**
+   * Receive a message from a socket
+   *
+   * @param fd file descriptor
+   * @param buffer buffer
+   * @param count length
+   * @param flags flag. see https://man7.org/linux/man-pages/man2/recvmsg.2.html
+   * @return zero on success. -1 on error
+   * @throws LastErrorException if error occurs
+   */
+  public static native int recv(int fd, byte[] buffer, int count, int flags)
+      throws LastErrorException;
+
+  /**
+   * Send a message to a socket
+   *
+   * @param fd file descriptor
+   * @param buffer buffer
+   * @param count length
+   * @param flags flag. see https://man7.org/linux/man-pages/man2/sendmsg.2.html
+   * @return zero on success. -1 on error
+   * @throws LastErrorException if error occurs
+   */
+  public static native int send(int fd, byte[] buffer, int count, int flags)
+      throws LastErrorException;
+
+  /**
+   * Close socket
+   *
+   * @param fd file descriptor
+   * @return zero on success. -1 on error
+   * @throws LastErrorException if error occurs
+   */
+  public static native int close(int fd) throws LastErrorException;
+
+  /**
+   * return a description of the error code passed in the argument errnum.
+   *
+   * @param errno error pointer
+   * @return error description
+   */
+  public static native String strerror(int errno);
+
+  private static String formatError(LastErrorException lee) {
+    try {
+      return strerror(lee.getErrorCode());
+    } catch (Throwable t) {
+      return lee.getMessage();
+    }
+  }
+
+  @Override
+  public boolean isConnected() {
+    return connected;
+  }
+
+  @Override
+  public void close() throws IOException {
+    if (!closeLock.getAndSet(true)) {
+      try {
+        close(fd);
+      } catch (LastErrorException lee) {
+        throw new IOException("native close() failed : " + formatError(lee));
+      }
+      connected = false;
+    }
+  }
+
+  public void connect(SocketAddress endpoint, int timeout) throws IOException {
+    try {
+      int ret = connect(fd, sockaddr, sockaddr.size());
+      if (ret != 0) {
+        throw new IOException(strerror(Native.getLastError()));
+      }
+      connected = true;
+    } catch (LastErrorException lee) {
+      try {
+        close();
+      } catch (IOException e) {
+      }
+
+      throw new IOException("native connect() failed : " + formatError(lee));
+    }
+    is = new UnixSocketInputStream();
+    os = new UnixSocketOutputStream();
+  }
+
+  public InputStream getInputStream() {
+    return is;
+  }
+
+  public OutputStream getOutputStream() {
+    return os;
+  }
+
+  public void setTcpNoDelay(boolean b) {
+    // do nothing
+  }
+
+  public void setKeepAlive(boolean b) {
+    // do nothing
+  }
+
+  public void setSoLinger(boolean b, int i) {
+    // do nothing
+  }
+
+  public void setSoTimeout(int timeout) {
+    // do nothing
+  }
+
+  public void shutdownInput() {
+    // do nothing
+  }
+
+  public void shutdownOutput() {
+    // do nothing
+  }
+
+  /** Socket address */
+  public static class SockAddr extends Structure {
+    /** socket family */
+    public short sun_family = AF_UNIX;
+    /** pathname */
+    public byte[] sun_path;
+
+    /**
+     * Constructor.
+     *
+     * @param sunPath path
+     */
+    public SockAddr(String sunPath) {
+      byte[] arr = sunPath.getBytes();
+      sun_path = new byte[arr.length + 1];
+      System.arraycopy(arr, 0, sun_path, 0, Math.min(sun_path.length - 1, arr.length));
+      allocateMemory();
+    }
+
+    @Override
+    protected java.util.List<String> getFieldOrder() {
+      return Arrays.asList("sun_family", "sun_path");
+    }
+  }
+
+  class UnixSocketInputStream extends InputStream {
+
+    @Override
+    public int read(byte[] bytesEntry, int off, int len) throws IOException {
+      try {
+        return recv(fd, bytesEntry, len, 0);
+      } catch (LastErrorException lee) {
+        throw new IOException("native read() failed : " + formatError(lee));
+      }
+    }
+
+    @Override
+    public int read() throws IOException {
+      byte[] bytes = new byte[1];
+      int bytesRead = read(bytes);
+      if (bytesRead == 0) {
+        return -1;
+      }
+      return bytes[0] & 0xff;
+    }
+
+    @Override
+    public int read(byte[] bytes) throws IOException {
+      return read(bytes, 0, bytes.length);
+    }
+  }
+
+  class UnixSocketOutputStream extends OutputStream {
+
+    @Override
+    public void write(byte[] bytesEntry, int off, int len) throws IOException {
+      int bytes;
+      try {
+        bytes = send(fd, bytesEntry, len, 0);
+
+        if (bytes != len) {
+          throw new IOException("can't write " + len + "bytes");
+        }
+      } catch (LastErrorException lee) {
+        throw new IOException("native write() failed : " + formatError(lee));
+      }
+    }
+
+    @Override
+    public void write(int value) throws IOException {}
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/tls/HostnameVerifier.java b/src/main/java/org/mariadb/jdbc/client/tls/HostnameVerifier.java
new file mode 100644
index 0000000..393f57f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/tls/HostnameVerifier.java
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.tls;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.*;
+import java.util.regex.Pattern;
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import javax.net.ssl.SSLException;
+import javax.security.auth.x500.X500Principal;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** SSL host verification */
+public class HostnameVerifier {
+
+  private static final Logger logger = Loggers.getLogger(HostnameVerifier.class);
+  private static final Pattern IP_V4 =
+      Pattern.compile(
+          "^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.)"
+              + "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){2}"
+              + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
+  private static final Pattern IP_V6 = Pattern.compile("^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$");
+  private static final Pattern IP_V6_COMPRESSED =
+      Pattern.compile(
+          "^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)"
+              + "::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)$");
+
+  /**
+   * DNS verification : Matching is performed using the matching rules specified by [RFC2459]. If
+   * more than one identity of a given type is present in the certificate (e.g., more than one
+   * dNSName name, a match in any one of the set is considered acceptable.) Names may contain the
+   * wildcard character * which is considered to match any single domain name component or component
+   * fragment. E.g., *.a.com matches foo.a.com but not bar.foo.a.com. f*.com matches foo.com but not
+   * bar.com.
+   *
+   * @param hostname hostname
+   * @param tlsDnsPattern DNS pattern (may contain wildcard)
+   * @return true if matching
+   */
+  private static boolean matchDns(String hostname, String tlsDnsPattern) throws SSLException {
+    boolean hostIsIp = isIPv4(hostname) || isIPv6(hostname);
+    StringTokenizer hostnameSt = new StringTokenizer(hostname.toLowerCase(Locale.ROOT), ".");
+    StringTokenizer templateSt = new StringTokenizer(tlsDnsPattern.toLowerCase(Locale.ROOT), ".");
+    if (hostnameSt.countTokens() != templateSt.countTokens()) {
+      return false;
+    }
+
+    try {
+      while (hostnameSt.hasMoreTokens()) {
+        if (!matchWildCards(hostIsIp, hostnameSt.nextToken(), templateSt.nextToken())) {
+          return false;
+        }
+      }
+    } catch (SSLException exception) {
+      throw new SSLException(
+          normalizedHostMsg(hostname)
+              + " doesn't correspond to certificate CN \""
+              + tlsDnsPattern
+              + "\" : wildcards not possible for IPs");
+    }
+    return true;
+  }
+
+  private static boolean matchWildCards(boolean hostIsIp, String hostnameToken, String tlsDnsToken)
+      throws SSLException {
+    int wildcardIndex = tlsDnsToken.indexOf("*");
+    String token = hostnameToken;
+    if (wildcardIndex != -1) {
+      if (hostIsIp) {
+        throw new SSLException("WildCards not possible when using IP's");
+      }
+      boolean first = true;
+      String beforeWildcard;
+      String afterWildcard = tlsDnsToken;
+
+      while (wildcardIndex != -1) {
+        beforeWildcard = afterWildcard.substring(0, wildcardIndex);
+        afterWildcard = afterWildcard.substring(wildcardIndex + 1);
+
+        int beforeStartIdx = token.indexOf(beforeWildcard);
+        if ((beforeStartIdx == -1) || (first && beforeStartIdx != 0)) {
+          return false;
+        }
+
+        first = false;
+
+        token = token.substring(beforeStartIdx + beforeWildcard.length());
+        wildcardIndex = afterWildcard.indexOf("*");
+      }
+      return token.endsWith(afterWildcard);
+    }
+
+    // no wildcard -> token must be equal.
+    return token.equals(tlsDnsToken);
+  }
+
+  private static String extractCommonName(String principal) throws SSLException {
+    if (principal == null) {
+      return null;
+    }
+    try {
+      LdapName ldapName = new LdapName(principal);
+
+      for (Rdn rdn : ldapName.getRdns()) {
+        if (rdn.getType().equalsIgnoreCase("CN")) {
+          Object obj = rdn.getValue();
+          if (obj != null) {
+            return obj.toString();
+          }
+        }
+      }
+      return null;
+    } catch (InvalidNameException e) {
+      throw new SSLException("DN value \"" + principal + "\" is invalid");
+    }
+  }
+
+  private static String normaliseAddress(String hostname) {
+    try {
+      if (hostname == null) {
+        return null;
+      }
+      InetAddress inetAddress = InetAddress.getByName(hostname);
+      return inetAddress.getHostAddress();
+    } catch (UnknownHostException unexpected) {
+      return hostname;
+    }
+  }
+
+  private static String normalizedHostMsg(String normalizedHost) {
+    StringBuilder msg = new StringBuilder();
+    if (isIPv4(normalizedHost)) {
+      msg.append("IPv4 host \"");
+    } else if (isIPv6(normalizedHost)) {
+      msg.append("IPv6 host \"");
+    } else {
+      msg.append("DNS host \"");
+    }
+    msg.append(normalizedHost).append("\"");
+    return msg.toString();
+  }
+
+  /**
+   * check if ip correspond to IPV4
+   *
+   * @param ip ip value
+   * @return if ip is using IPV4 format
+   */
+  public static boolean isIPv4(final String ip) {
+    return IP_V4.matcher(ip).matches();
+  }
+
+  /**
+   * check if ip correspond to IPV6
+   *
+   * @param ip ip value
+   * @return if ip is using IPV6 format
+   */
+  public static boolean isIPv6(final String ip) {
+    return IP_V6.matcher(ip).matches() || IP_V6_COMPRESSED.matcher(ip).matches();
+  }
+
+  private static SubjectAltNames getSubjectAltNames(X509Certificate cert)
+      throws CertificateParsingException {
+    Collection<List<?>> entries = cert.getSubjectAlternativeNames();
+    SubjectAltNames subjectAltNames = new SubjectAltNames();
+    if (entries != null) {
+      for (List<?> entry : entries) {
+        if (entry.size() >= 2) {
+          int type = (Integer) entry.get(0);
+
+          if (type == 2) { // DNS
+            String altNameDns = (String) entry.get(1);
+            if (altNameDns != null) {
+              String normalizedSubjectAlt = altNameDns.toLowerCase(Locale.ROOT);
+              subjectAltNames.add(new GeneralName(normalizedSubjectAlt, Extension.DNS));
+            }
+          }
+
+          if (type == 7) { // IP
+            String altNameIp = (String) entry.get(1);
+            if (altNameIp != null) {
+              subjectAltNames.add(new GeneralName(altNameIp, Extension.IP));
+            }
+          }
+        }
+      }
+    }
+    return subjectAltNames;
+  }
+
+  /**
+   * Verification that throw an exception with a detailed error message in case of error.
+   *
+   * @param host hostname
+   * @param cert certificate
+   * @param serverThreadId server thread Identifier to identify connection in logs
+   * @throws SSLException exception
+   */
+  public static void verify(String host, X509Certificate cert, long serverThreadId)
+      throws SSLException {
+    if (host == null) {
+      return; // no validation if no host (possible for name pipe)
+    }
+    String lowerCaseHost = host.toLowerCase(Locale.ROOT);
+    try {
+      // ***********************************************************
+      // RFC 6125 : check Subject Alternative Name (SAN)
+      // ***********************************************************
+      SubjectAltNames subjectAltNames = getSubjectAltNames(cert);
+      if (!subjectAltNames.isEmpty()) {
+
+        // ***********************************************************
+        // Host is IPv4 : Check corresponding entries in subject alternative names
+        // ***********************************************************
+        if (isIPv4(lowerCaseHost)) {
+          for (GeneralName entry : subjectAltNames.getGeneralNames()) {
+            if (logger.isTraceEnabled()) {
+              logger.trace(
+                  "Conn={}. IPv4 verification of hostname : type={} value={} to {}",
+                  serverThreadId,
+                  entry.extension,
+                  entry.value,
+                  lowerCaseHost);
+            }
+
+            if (entry.extension == Extension.IP && lowerCaseHost.equals(entry.value)) {
+              return;
+            }
+          }
+        } else if (isIPv6(lowerCaseHost)) {
+          // ***********************************************************
+          // Host is IPv6 : Check corresponding entries in subject alternative names
+          // ***********************************************************
+          String normalisedHost = normaliseAddress(lowerCaseHost);
+          for (GeneralName entry : subjectAltNames.getGeneralNames()) {
+            if (logger.isTraceEnabled()) {
+              logger.trace(
+                  "Conn={}. IPv6 verification of hostname : type={} value={} to {}",
+                  serverThreadId,
+                  entry.extension,
+                  entry.value,
+                  lowerCaseHost);
+            }
+
+            if (entry.extension == Extension.IP
+                && !isIPv4(entry.value)
+                && normalisedHost.equals(normaliseAddress(entry.value))) {
+              return;
+            }
+          }
+        } else {
+          // ***********************************************************
+          // Host is not IP = DNS : Check corresponding entries in alternative subject names
+          // ***********************************************************
+          for (GeneralName entry : subjectAltNames.getGeneralNames()) {
+            if (logger.isTraceEnabled()) {
+              logger.trace(
+                  "Conn={}. DNS verification of hostname : type={} value={} to {}",
+                  serverThreadId,
+                  entry.extension,
+                  entry.value,
+                  lowerCaseHost);
+            }
+
+            if (entry.extension == Extension.DNS
+                && matchDns(lowerCaseHost, entry.value.toLowerCase(Locale.ROOT))) {
+              return;
+            }
+          }
+        }
+      }
+
+      // ***********************************************************
+      // RFC 2818 : legacy fallback using CN (recommendation is using alt-names)
+      // ***********************************************************
+      X500Principal subjectPrincipal = cert.getSubjectX500Principal();
+      String cn = extractCommonName(subjectPrincipal.getName(X500Principal.RFC2253));
+
+      if (cn == null) {
+        if (subjectAltNames.isEmpty()) {
+          throw new SSLException(
+              "CN not found in certificate principal \""
+                  + subjectPrincipal
+                  + "\" and certificate doesn't contain SAN");
+        } else {
+          throw new SSLException(
+              "CN not found in certificate principal \""
+                  + subjectPrincipal
+                  + "\" and "
+                  + normalizedHostMsg(lowerCaseHost)
+                  + " doesn't correspond to "
+                  + subjectAltNames);
+        }
+      }
+
+      String normalizedCn = cn.toLowerCase(Locale.ROOT);
+      if (logger.isTraceEnabled()) {
+        logger.trace(
+            "Conn={}. DNS verification of hostname : CN={} to {}",
+            serverThreadId,
+            normalizedCn,
+            lowerCaseHost);
+      }
+      if (!matchDns(lowerCaseHost, normalizedCn)) {
+        String errorMsg =
+            normalizedHostMsg(lowerCaseHost)
+                + " doesn't correspond to certificate CN \""
+                + normalizedCn
+                + "\"";
+        if (!subjectAltNames.isEmpty()) {
+          errorMsg += " and " + subjectAltNames;
+        }
+        throw new SSLException(errorMsg);
+      }
+
+    } catch (CertificateParsingException cpe) {
+      throw new SSLException("certificate parsing error : " + cpe.getMessage());
+    }
+  }
+
+  private enum Extension {
+    DNS,
+    IP
+  }
+
+  private static class GeneralName {
+
+    private final String value;
+    private final Extension extension;
+
+    public GeneralName(String value, Extension extension) {
+      this.value = value;
+      this.extension = extension;
+    }
+
+    @Override
+    public String toString() {
+      return "{" + extension + ":\"" + value + "\"}";
+    }
+  }
+
+  private static class SubjectAltNames {
+
+    private final List<GeneralName> generalNames = new ArrayList<>();
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("SAN[");
+      boolean first = true;
+
+      for (GeneralName generalName : generalNames) {
+        if (!first) {
+          sb.append(",");
+        }
+        first = false;
+        sb.append(generalName.toString());
+      }
+      sb.append("]");
+      return sb.toString();
+    }
+
+    public List<GeneralName> getGeneralNames() {
+      return generalNames;
+    }
+
+    public void add(GeneralName generalName) {
+      generalNames.add(generalName);
+    }
+
+    public boolean isEmpty() {
+      return generalNames.isEmpty();
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/tls/MariaDbX509KeyManager.java b/src/main/java/org/mariadb/jdbc/client/tls/MariaDbX509KeyManager.java
new file mode 100644
index 0000000..e879285
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/tls/MariaDbX509KeyManager.java
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.tls;
+
+import java.net.Socket;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.*;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * Key manager implementation that implement only client verification and rely only on private key
+ * for mutual authentication, without Server Name Indication (SNI) verification.
+ */
+public class MariaDbX509KeyManager extends X509ExtendedKeyManager {
+
+  private final Hashtable<String, KeyStore.PrivateKeyEntry> privateKeyHash = new Hashtable<>();
+
+  /**
+   * Creates Key manager.
+   *
+   * @param keyStore keyStore (must have been initialized)
+   * @param pwd keyStore password
+   * @throws KeyStoreException if keyStore hasn't been initialized.
+   */
+  public MariaDbX509KeyManager(KeyStore keyStore, char[] pwd) throws KeyStoreException {
+    super();
+    Enumeration<String> aliases = keyStore.aliases();
+    while (aliases.hasMoreElements()) {
+      String alias = aliases.nextElement();
+      if (keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
+        try {
+          privateKeyHash.put(
+              alias,
+              (KeyStore.PrivateKeyEntry)
+                  keyStore.getEntry(alias, new KeyStore.PasswordProtection(pwd)));
+        } catch (UnrecoverableEntryException | NoSuchAlgorithmException unrecoverableEntryEx) {
+          // password invalid | algorithm error
+        }
+      }
+    }
+  }
+
+  @Override
+  public String[] getClientAliases(String keyType, Principal[] issuers) {
+    List<String> accurateAlias = searchAccurateAliases(new String[] {keyType}, issuers);
+    if (accurateAlias.size() == 0) {
+      return null;
+    }
+    return accurateAlias.toArray(new String[0]);
+  }
+
+  @Override
+  public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
+    List<String> accurateAlias = searchAccurateAliases(keyType, issuers);
+    return accurateAlias == null || accurateAlias.isEmpty() ? null : accurateAlias.get(0);
+  }
+
+  @Override
+  public X509Certificate[] getCertificateChain(String alias) {
+    KeyStore.PrivateKeyEntry keyEntry = privateKeyHash.get(alias);
+    if (keyEntry == null) {
+      return null;
+    }
+
+    Certificate[] certs = keyEntry.getCertificateChain();
+    if (certs.length > 0 && certs[0] instanceof X509Certificate) {
+      return Arrays.copyOf(certs, certs.length, X509Certificate[].class);
+    }
+
+    return null;
+  }
+
+  @Override
+  public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
+    return chooseClientAlias(keyType, issuers, null);
+  }
+
+  @Override
+  public PrivateKey getPrivateKey(String alias) {
+    KeyStore.PrivateKeyEntry keyEntry = privateKeyHash.get(alias);
+    if (keyEntry == null) {
+      return null;
+    }
+    return keyEntry.getPrivateKey();
+  }
+
+  /**
+   * Search aliases corresponding to algorithms and issuers.
+   *
+   * @param keyTypes list of algorithms
+   * @param issuers list of issuers;
+   * @return list of corresponding aliases
+   */
+  private ArrayList<String> searchAccurateAliases(String[] keyTypes, Principal[] issuers) {
+    if (keyTypes == null || keyTypes.length == 0) {
+      return null;
+    }
+
+    ArrayList<String> accurateAliases = new ArrayList<>();
+    for (Map.Entry<String, KeyStore.PrivateKeyEntry> mapEntry : privateKeyHash.entrySet()) {
+
+      Certificate[] certs = mapEntry.getValue().getCertificateChain();
+      String alg = certs[0].getPublicKey().getAlgorithm();
+
+      for (String keyType : keyTypes) {
+        if (alg.equals(keyType)) {
+          if (issuers != null && issuers.length != 0) {
+            checkLoop:
+            for (Certificate cert : certs) {
+              if (cert instanceof X509Certificate) {
+                X500Principal certificateIssuer = ((X509Certificate) cert).getIssuerX500Principal();
+                for (Principal issuer : issuers) {
+                  if (certificateIssuer.equals(issuer)) {
+                    accurateAliases.add(mapEntry.getKey());
+                    break checkLoop;
+                  }
+                }
+              }
+            }
+          } else {
+            accurateAliases.add(mapEntry.getKey());
+          }
+        }
+      }
+    }
+    return accurateAliases;
+  }
+
+  @Override
+  public String[] getServerAliases(String keyType, Principal[] issuers) {
+    return null; // Driver use only client side
+  }
+
+  @Override
+  public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+    return null; // Driver use only client side
+  }
+
+  @Override
+  public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
+    return null; // Driver use only client side
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/tls/MariaDbX509TrustingManager.java b/src/main/java/org/mariadb/jdbc/client/tls/MariaDbX509TrustingManager.java
new file mode 100644
index 0000000..15c7b27
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/tls/MariaDbX509TrustingManager.java
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.tls;
+
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Class to accept any server certificate.
+ *
+ * <p>This permit to have network encrypted, BUT client doesn't validate server identity !!
+ */
+public class MariaDbX509TrustingManager implements X509TrustManager {
+
+  /** Constructor */
+  public MariaDbX509TrustingManager() {}
+
+  @Override
+  public void checkClientTrusted(X509Certificate[] x509Certificates, String string) {}
+
+  @Override
+  public void checkServerTrusted(X509Certificate[] x509Certificates, String string) {}
+
+  public X509Certificate[] getAcceptedIssuers() {
+    return null;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/util/MutableByte.java b/src/main/java/org/mariadb/jdbc/client/util/MutableByte.java
new file mode 100644
index 0000000..ccec43b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/util/MutableByte.java
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.util;
+
+/** Mutable int, permitting to update packet sequence */
+public class MutableByte {
+  private byte value = -1;
+
+  /**
+   * Set new sequence value
+   *
+   * @param value new value
+   */
+  public void set(byte value) {
+    this.value = value;
+  }
+
+  /**
+   * Get current sequence value
+   *
+   * @return value
+   */
+  public byte get() {
+    return this.value;
+  }
+
+  /**
+   * Increment sequence and get new value
+   *
+   * @return new value
+   */
+  public byte incrementAndGet() {
+    return ++value;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/util/MutableInt.java b/src/main/java/org/mariadb/jdbc/client/util/MutableInt.java
new file mode 100644
index 0000000..a9657f6
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/util/MutableInt.java
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.util;
+
+/** Mutable int */
+public class MutableInt {
+  private int value = -1;
+
+  /**
+   * Set new sequence value
+   *
+   * @param value new value
+   */
+  public void set(int value) {
+    this.value = value;
+  }
+
+  /**
+   * Get current sequence value
+   *
+   * @return value
+   */
+  public int get() {
+    return this.value;
+  }
+
+  /**
+   * Increment sequence and get new value
+   *
+   * @return new value
+   */
+  public int incrementAndGet() {
+    return ++value;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/util/Parameter.java b/src/main/java/org/mariadb/jdbc/client/util/Parameter.java
new file mode 100644
index 0000000..0f41bef
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/util/Parameter.java
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.util;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+
+/** Parameter */
+public interface Parameter {
+
+  /**
+   * Encode parameter in text format
+   *
+   * @param encoder packet writer
+   * @param context connection context
+   * @throws IOException if socket error occurs
+   * @throws SQLException if other kind of error occurs
+   */
+  void encodeText(Writer encoder, Context context) throws IOException, SQLException;
+
+  /**
+   * Encode parameter in binary format
+   *
+   * @param encoder packet writer
+   * @throws IOException if socket error occurs
+   * @throws SQLException if other kind of error occurs
+   */
+  void encodeBinary(Writer encoder) throws IOException, SQLException;
+
+  /**
+   * Encode parameter in binary long format
+   *
+   * @param encoder packet writer
+   * @throws IOException if socket error occurs
+   * @throws SQLException if other kind of error occurs
+   */
+  void encodeLongData(Writer encoder) throws IOException, SQLException;
+
+  /**
+   * transform parameter in byte array
+   *
+   * @return bytes
+   * @throws IOException if socket error occurs
+   * @throws SQLException if other kind of error occurs
+   */
+  byte[] encodeData() throws IOException, SQLException;
+
+  /**
+   * Can parameter be encoded in binary long format
+   *
+   * @return can parameter be encoded in binary long format
+   */
+  boolean canEncodeLongData();
+
+  /**
+   * return binary encoding type
+   *
+   * @return binary encoding type
+   */
+  int getBinaryEncodeType();
+
+  /**
+   * is parameter null
+   *
+   * @return is null
+   */
+  boolean isNull();
+
+  /**
+   * Methods to return parameter as string if possible (Streaming parameter will return null)
+   *
+   * @param context current connection context
+   * @return null if not available.
+   */
+  String bestEffortStringValue(Context context);
+}
diff --git a/src/main/java/org/mariadb/jdbc/client/util/Parameters.java b/src/main/java/org/mariadb/jdbc/client/util/Parameters.java
new file mode 100644
index 0000000..dc42f18
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/client/util/Parameters.java
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.client.util;
+
+/** Parameters list */
+public interface Parameters {
+
+  /**
+   * get parameter at index
+   *
+   * @param index index
+   * @return parameter
+   */
+  Parameter get(int index);
+
+  /**
+   * is there a parameter at requested index
+   *
+   * @param index index
+   * @return indicate if there is a parameter at index
+   */
+  boolean containsKey(int index);
+
+  /**
+   * Set parameter at index
+   *
+   * @param index index
+   * @param element parameter
+   */
+  void set(int index, Parameter element);
+
+  /**
+   * list size
+   *
+   * @return list size
+   */
+  int size();
+
+  /**
+   * Clone parameter list
+   *
+   * @return parameter list
+   */
+  Parameters clone();
+}
diff --git a/src/main/java/org/mariadb/jdbc/codec/NonNullParameter.java b/src/main/java/org/mariadb/jdbc/codec/NonNullParameter.java
new file mode 100644
index 0000000..aca1704
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/codec/NonNullParameter.java
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.codec;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/**
+ * Parameter wrapper for primitive, knowing that value cannot be null, permitting fast path for few
+ * methods.
+ *
+ * @param <T> value type
+ */
+public class NonNullParameter<T> extends Parameter<T> {
+
+  public NonNullParameter(Codec<T> codec, T value) {
+    super(codec, value);
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context) throws IOException, SQLException {
+    codec.encodeText(encoder, context, this.value, null, length);
+  }
+
+  @Override
+  public boolean isNull() {
+    return false;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/codec/Parameter.java b/src/main/java/org/mariadb/jdbc/codec/Parameter.java
new file mode 100644
index 0000000..3367bf4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/codec/Parameter.java
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.codec;
+
+import java.io.IOException;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.socket.impl.PacketWriter;
+import org.mariadb.jdbc.plugin.Codec;
+
+public class Parameter<T> implements org.mariadb.jdbc.client.util.Parameter {
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  public static final Parameter<?> NULL_PARAMETER =
+      new Parameter(null, null) {
+        @Override
+        public int getBinaryEncodeType() {
+          return DataType.VARCHAR.get();
+        }
+
+        @Override
+        public boolean isNull() {
+          return true;
+        }
+      };
+
+  protected final Codec<T> codec;
+  protected final T value;
+  protected final Long length;
+
+  public Parameter(Codec<T> codec, T value) {
+    this.codec = codec;
+    this.value = value;
+    this.length = null;
+  }
+
+  public Parameter(Codec<T> codec, T value, Long length) {
+    this.codec = codec;
+    this.value = value;
+    this.length = length;
+  }
+
+  public void encodeText(Writer encoder, Context context) throws IOException, SQLException {
+    if (value == null) {
+      encoder.writeAscii("null");
+    } else {
+      codec.encodeText(encoder, context, this.value, null, length);
+    }
+  }
+
+  public void encodeBinary(Writer encoder) throws IOException, SQLException {
+    codec.encodeBinary(encoder, this.value, null, length);
+  }
+
+  public void encodeLongData(Writer encoder) throws IOException, SQLException {
+    codec.encodeLongData(encoder, this.value, length);
+  }
+
+  public byte[] encodeData() throws IOException, SQLException {
+    return codec.encodeData(this.value, length);
+  }
+
+  public boolean canEncodeLongData() {
+    return codec.canEncodeLongData();
+  }
+
+  public int getBinaryEncodeType() {
+    return codec.getBinaryEncodeType();
+  }
+
+  public boolean isNull() {
+    return value == null;
+  }
+
+  public String bestEffortStringValue(Context context) {
+    if (isNull()) return "null";
+    if (codec.canEncodeLongData()) {
+      Type it = codec.getClass().getGenericInterfaces()[0];
+      ParameterizedType parameterizedType = (ParameterizedType) it;
+      Type typeParameter = parameterizedType.getActualTypeArguments()[0];
+      return "<" + typeParameter + ">";
+    }
+    try {
+      PacketWriter writer = new PacketWriter(null, 0, 0xffffff, null, null);
+      codec.encodeText(writer, context, this.value, null, this.length);
+      return new String(writer.buf(), 4, writer.pos() - 4, StandardCharsets.UTF_8);
+    } catch (Throwable t) {
+      return null;
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/codec/ParameterWithCal.java b/src/main/java/org/mariadb/jdbc/codec/ParameterWithCal.java
new file mode 100644
index 0000000..bfcd18a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/codec/ParameterWithCal.java
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.codec;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+public class ParameterWithCal<T> extends Parameter<T> {
+
+  private final Calendar cal;
+
+  public ParameterWithCal(Codec<T> codec, T value, Calendar cal) {
+    super(codec, value);
+    this.cal = cal;
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context) throws IOException, SQLException {
+    codec.encodeText(encoder, context, this.value, this.cal, length);
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder) throws IOException, SQLException {
+    codec.encodeBinary(encoder, this.value, this.cal, length);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/export/ExceptionFactory.java b/src/main/java/org/mariadb/jdbc/export/ExceptionFactory.java
new file mode 100644
index 0000000..a90aaee
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/export/ExceptionFactory.java
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.export;
+
+import java.sql.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.MariaDbPoolConnection;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.message.server.OkPacket;
+
+/**
+ * Exception factory. This permit common error logging, with thread id, dump query, and specific
+ * dead-lock additional information
+ */
+public class ExceptionFactory {
+
+  private static final Set<Integer> LOCK_DEADLOCK_ERROR_CODES =
+      new HashSet<>(Arrays.asList(1205, 1213, 1614));
+  private final Configuration conf;
+  private final HostAddress hostAddress;
+  private Connection connection;
+  private MariaDbPoolConnection poolConnection;
+  private long threadId;
+  private Statement statement;
+
+  /**
+   * Connection Exception factory constructor
+   *
+   * @param conf configuration
+   * @param hostAddress current host
+   */
+  public ExceptionFactory(Configuration conf, HostAddress hostAddress) {
+    this.conf = conf;
+    this.hostAddress = hostAddress;
+  }
+
+  private ExceptionFactory(
+      Connection connection,
+      MariaDbPoolConnection poolConnection,
+      Configuration conf,
+      HostAddress hostAddress,
+      long threadId,
+      Statement statement) {
+    this.connection = connection;
+    this.poolConnection = poolConnection;
+    this.conf = conf;
+    this.hostAddress = hostAddress;
+    this.threadId = threadId;
+    this.statement = statement;
+  }
+
+  private static String buildMsgText(
+      String initialMessage,
+      long threadId,
+      Configuration conf,
+      String sql,
+      int errorCode,
+      Connection connection) {
+
+    StringBuilder msg = new StringBuilder();
+
+    if (threadId != 0L) {
+      msg.append("(conn=").append(threadId).append(") ");
+    }
+    msg.append(initialMessage);
+
+    if (conf.dumpQueriesOnException() && sql != null) {
+      if (conf.maxQuerySizeToLog() != 0 && sql.length() > conf.maxQuerySizeToLog() - 3) {
+        msg.append("\nQuery is: ").append(sql, 0, conf.maxQuerySizeToLog() - 3).append("...");
+      } else {
+        msg.append("\nQuery is: ").append(sql);
+      }
+    }
+
+    if (conf.includeInnodbStatusInDeadlockExceptions()
+        && LOCK_DEADLOCK_ERROR_CODES.contains(errorCode)
+        && connection != null) {
+      Statement stmt = connection.createStatement();
+      try {
+        ResultSet rs = stmt.executeQuery("SHOW ENGINE INNODB STATUS");
+        rs.next();
+        msg.append("\ndeadlock information: ").append(rs.getString(3));
+      } catch (SQLException sqle) {
+        // eat
+      }
+    }
+
+    if (conf.includeThreadDumpInDeadlockExceptions()
+        && LOCK_DEADLOCK_ERROR_CODES.contains(errorCode)) {
+      msg.append("\nthread name: ").append(Thread.currentThread().getName());
+      msg.append("\ncurrent threads: ");
+      Thread.getAllStackTraces()
+          .forEach(
+              (thread, traces) -> {
+                msg.append("\n  name:\"")
+                    .append(thread.getName())
+                    .append("\" pid:")
+                    .append(thread.getId())
+                    .append(" status:")
+                    .append(thread.getState());
+                for (StackTraceElement trace : traces) {
+                  msg.append("\n    ").append(trace);
+                }
+              });
+    }
+
+    return msg.toString();
+  }
+
+  /**
+   * Set connection
+   *
+   * @param oldExceptionFactory previous connection exception factory
+   */
+  public void setConnection(ExceptionFactory oldExceptionFactory) {
+    this.connection = oldExceptionFactory.connection;
+  }
+
+  /**
+   * Set connection to factory
+   *
+   * @param connection connection
+   * @return this {@link ExceptionFactory}
+   */
+  public ExceptionFactory setConnection(Connection connection) {
+    this.connection = connection;
+    return this;
+  }
+
+  /**
+   * Set pool connection to factory
+   *
+   * @param internalPoolConnection internal pool connection
+   * @return this {@link ExceptionFactory}
+   */
+  public ExceptionFactory setPoolConnection(MariaDbPoolConnection internalPoolConnection) {
+    this.poolConnection = internalPoolConnection;
+    return this;
+  }
+
+  /**
+   * Set connection thread id
+   *
+   * @param threadId connection thread id
+   */
+  public void setThreadId(long threadId) {
+    this.threadId = threadId;
+  }
+
+  /**
+   * Create a BatchUpdateException, filling successful updates
+   *
+   * @param res completion list
+   * @param length expected size
+   * @param sqle exception
+   * @return BatchUpdateException object
+   */
+  public BatchUpdateException createBatchUpdate(
+      List<Completion> res, int length, SQLException sqle) {
+    int[] updateCounts = new int[length];
+    for (int i = 0; i < length; i++) {
+      if (i < res.size()) {
+        if (res.get(i) instanceof OkPacket) {
+          updateCounts[i] = (int) ((OkPacket) res.get(i)).getAffectedRows();
+        } else {
+          updateCounts[i] = org.mariadb.jdbc.Statement.SUCCESS_NO_INFO;
+        }
+      } else {
+        updateCounts[i] = org.mariadb.jdbc.Statement.EXECUTE_FAILED;
+      }
+    }
+    return new BatchUpdateException(
+        sqle.getMessage(), sqle.getSQLState(), sqle.getErrorCode(), updateCounts, sqle);
+  }
+
+  /**
+   * Create a BatchUpdateException, filling successful updates
+   *
+   * @param res completion list
+   * @param length expected length
+   * @param responseMsg successful response
+   * @param sqle exception
+   * @return BatchUpdateException object
+   */
+  public BatchUpdateException createBatchUpdate(
+      List<Completion> res, int length, int[] responseMsg, SQLException sqle) {
+    int[] updateCounts = new int[length];
+
+    int responseIncrement = 0;
+    for (int i = 0; i < length; i++) {
+      if (i >= responseMsg.length) {
+        Arrays.fill(updateCounts, i, length, Statement.EXECUTE_FAILED);
+        break;
+      }
+      int MsgResponseNo = responseMsg[i];
+      if (MsgResponseNo < 1) {
+        updateCounts[responseIncrement++] = Statement.EXECUTE_FAILED;
+        return new BatchUpdateException(updateCounts, sqle);
+      } else if (MsgResponseNo == 1 && res.size() > i && res.get(i) instanceof OkPacket) {
+        updateCounts[i] = (int) ((OkPacket) res.get(i)).getAffectedRows();
+      } else {
+        // unknown.
+        updateCounts[i] = Statement.SUCCESS_NO_INFO;
+      }
+    }
+    return new BatchUpdateException(
+        sqle.getMessage(), sqle.getSQLState(), sqle.getErrorCode(), updateCounts, sqle);
+  }
+
+  /**
+   * Construct an Exception factory from this + adding current statement
+   *
+   * @param statement current statement
+   * @return new Exception factory
+   */
+  public ExceptionFactory of(Statement statement) {
+    return new ExceptionFactory(
+        this.connection,
+        this.poolConnection,
+        this.conf,
+        this.hostAddress,
+        this.threadId,
+        statement);
+  }
+
+  /**
+   * Construct an Exception factory from this + adding current SQL
+   *
+   * @param sql current sql command
+   * @return new Exception factory
+   */
+  public ExceptionFactory withSql(String sql) {
+    return new SqlExceptionFactory(
+        this.connection,
+        this.poolConnection,
+        this.conf,
+        this.hostAddress,
+        this.threadId,
+        statement,
+        sql);
+  }
+
+  private SQLException createException(
+      String initialMessage, String sqlState, int errorCode, Exception cause) {
+
+    String msg = buildMsgText(initialMessage, threadId, conf, getSql(), errorCode, connection);
+
+    if ("70100".equals(sqlState)) { // ER_QUERY_INTERRUPTED
+      return new SQLTimeoutException(msg, sqlState, errorCode);
+    }
+    // 4166 : mariadb load data infile disable
+    // 1148 : 10.2 mariadb load data infile disable
+    // 3948 : mysql load data infile disable
+    if ((errorCode == 4166 || errorCode == 3948 || errorCode == 1148) && !conf.allowLocalInfile()) {
+      return new SQLException(
+          "Local infile is disabled by connector. Enable `allowLocalInfile` to allow local infile"
+              + " commands",
+          sqlState,
+          errorCode,
+          cause);
+    }
+
+    SQLException returnEx;
+    String sqlClass = sqlState == null ? "42" : sqlState.substring(0, 2);
+    switch (sqlClass) {
+      case "0A":
+        returnEx = new SQLFeatureNotSupportedException(msg, sqlState, errorCode, cause);
+        break;
+      case "22":
+      case "26":
+      case "2F":
+      case "20":
+      case "42":
+      case "XA":
+        returnEx = new SQLSyntaxErrorException(msg, sqlState, errorCode, cause);
+        break;
+      case "25":
+      case "28":
+        returnEx = new SQLInvalidAuthorizationSpecException(msg, sqlState, errorCode, cause);
+        break;
+      case "21":
+      case "23":
+        returnEx = new SQLIntegrityConstraintViolationException(msg, sqlState, errorCode, cause);
+        break;
+      case "08":
+        returnEx = new SQLNonTransientConnectionException(msg, sqlState, errorCode, cause);
+        break;
+      case "40":
+        returnEx = new SQLTransactionRollbackException(msg, sqlState, errorCode, cause);
+        break;
+      case "HY":
+        returnEx = new SQLException(msg, sqlState, errorCode, cause);
+        break;
+      default:
+        returnEx = new SQLTransientConnectionException(msg, sqlState, errorCode, cause);
+        break;
+    }
+
+    if (poolConnection != null) {
+      if (statement != null && statement instanceof PreparedStatement) {
+        poolConnection.fireStatementErrorOccurred((PreparedStatement) statement, returnEx);
+      }
+      if (returnEx instanceof SQLNonTransientConnectionException
+          || returnEx instanceof SQLTransientConnectionException) {
+        poolConnection.fireConnectionErrorOccurred(returnEx);
+      }
+    }
+
+    return returnEx;
+  }
+
+  /**
+   * fast creation of SQLFeatureNotSupportedException exception
+   *
+   * @param message error message
+   * @return exception to be thrown
+   */
+  public SQLException notSupported(String message) {
+    return createException(message, "0A000", -1, null);
+  }
+
+  /**
+   * Creation of an exception
+   *
+   * @param message error message
+   * @return exception to be thrown
+   */
+  public SQLException create(String message) {
+    return createException(message, "42000", -1, null);
+  }
+
+  /**
+   * Creation of an exception
+   *
+   * @param message error message
+   * @param sqlState sql state
+   * @return exception to be thrown
+   */
+  public SQLException create(String message, String sqlState) {
+    return createException(message, sqlState, -1, null);
+  }
+
+  /**
+   * Creation of an exception
+   *
+   * @param message error message
+   * @param sqlState sql state
+   * @param cause initial exception
+   * @return exception to be thrown
+   */
+  public SQLException create(String message, String sqlState, Exception cause) {
+    return createException(message, sqlState, -1, cause);
+  }
+  /**
+   * Creation of an exception
+   *
+   * @param message error message
+   * @param sqlState sql state
+   * @param errorCode error code
+   * @return exception to be thrown
+   */
+  public SQLException create(String message, String sqlState, int errorCode) {
+    return createException(message, sqlState, errorCode, null);
+  }
+
+  /**
+   * get SQL command
+   *
+   * @return sql command
+   */
+  public String getSql() {
+    return null;
+  }
+
+  /** Exception with SQL command */
+  public class SqlExceptionFactory extends ExceptionFactory {
+    private final String sql;
+
+    /**
+     * Constructor of Exception factory with SQL
+     *
+     * @param connection connection
+     * @param poolConnection pool connection
+     * @param conf configuration
+     * @param hostAddress host
+     * @param threadId connection thread id
+     * @param statement statement
+     * @param sql sql
+     */
+    public SqlExceptionFactory(
+        Connection connection,
+        MariaDbPoolConnection poolConnection,
+        Configuration conf,
+        HostAddress hostAddress,
+        long threadId,
+        Statement statement,
+        String sql) {
+      super(connection, poolConnection, conf, hostAddress, threadId, statement);
+      this.sql = sql;
+    }
+
+    @Override
+    public String getSql() {
+      return sql;
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/export/HaMode.java b/src/main/java/org/mariadb/jdbc/export/HaMode.java
new file mode 100644
index 0000000..4a1267c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/export/HaMode.java
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.export;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentMap;
+import org.mariadb.jdbc.HostAddress;
+
+/** Failover (High-availability) mode */
+public enum HaMode {
+  /** replication mode : first is primary, other are replica */
+  REPLICATION("replication") {
+    public Optional<HostAddress> getAvailableHost(
+        List<HostAddress> hostAddresses,
+        ConcurrentMap<HostAddress, Long> denyList,
+        boolean primary) {
+      return HaMode.getAvailableRoundRobinHost(this, hostAddresses, denyList, primary);
+    }
+  },
+  /** sequential: driver will always connect according to connection string order */
+  SEQUENTIAL("sequential") {
+    public Optional<HostAddress> getAvailableHost(
+        List<HostAddress> hostAddresses,
+        ConcurrentMap<HostAddress, Long> denyList,
+        boolean primary) {
+      return getAvailableHostInOrder(hostAddresses, denyList, primary);
+    }
+  },
+  /**
+   * load-balance: driver will connect to any host using round-robin, permitting balancing
+   * connections
+   */
+  LOADBALANCE("load-balance") {
+    public Optional<HostAddress> getAvailableHost(
+        List<HostAddress> hostAddresses,
+        ConcurrentMap<HostAddress, Long> denyList,
+        boolean primary) {
+      return HaMode.getAvailableRoundRobinHost(this, hostAddresses, denyList, primary);
+    }
+  },
+  /** no ha-mode. Connect to first host only */
+  NONE("") {
+    public Optional<HostAddress> getAvailableHost(
+        List<HostAddress> hostAddresses,
+        ConcurrentMap<HostAddress, Long> denyList,
+        boolean primary) {
+      return hostAddresses.isEmpty() ? Optional.empty() : Optional.of(hostAddresses.get(0));
+    }
+  };
+
+  private final String value;
+  private HostAddress lastRoundRobinPrimaryHost = null;
+  private HostAddress lastRoundRobinSecondaryHost = null;
+
+  HaMode(String value) {
+    this.value = value;
+  }
+
+  /**
+   * Get HAMode from values or aliases
+   *
+   * @param value value or alias
+   * @return HaMode if corresponding mode is found
+   */
+  public static HaMode from(String value) {
+    for (HaMode haMode : values()) {
+      if (haMode.value.equalsIgnoreCase(value) || haMode.name().equalsIgnoreCase(value)) {
+        return haMode;
+      }
+    }
+    throw new IllegalArgumentException(
+        String.format("Wrong argument value '%s' for HaMode", value));
+  }
+
+  /**
+   * return hosts of corresponding type (primary or not) without blacklisted hosts. hosts in
+   * blacklist reaching blacklist timeout will be present. order corresponds to connection string
+   * order.
+   *
+   * @param hostAddresses hosts
+   * @param denyList blacklist
+   * @param primary returns primary hosts or replica
+   * @return list without denied hosts
+   */
+  public static Optional<HostAddress> getAvailableHostInOrder(
+      List<HostAddress> hostAddresses, ConcurrentMap<HostAddress, Long> denyList, boolean primary) {
+    // use in order not blacklisted server
+    for (HostAddress hostAddress : hostAddresses) {
+      if (hostAddress.primary == primary) {
+        if (!denyList.containsKey(hostAddress)) return Optional.of(hostAddress);
+        if (denyList.get(hostAddress) < System.currentTimeMillis()) {
+          // timeout reached
+          denyList.remove(hostAddress);
+          return Optional.of(hostAddress);
+        }
+      }
+    }
+    return Optional.empty();
+  }
+
+  /**
+   * return hosts of corresponding type (primary or not) without blacklisted hosts. hosts in
+   * blacklist reaching blacklist timeout will be present, RoundRobin Order.
+   *
+   * @param haMode current haMode
+   * @param hostAddresses hosts
+   * @param denyList blacklist
+   * @param primary returns primary hosts or replica
+   * @return list without denied hosts
+   */
+  public static Optional<HostAddress> getAvailableRoundRobinHost(
+      HaMode haMode,
+      List<HostAddress> hostAddresses,
+      ConcurrentMap<HostAddress, Long> denyList,
+      boolean primary) {
+    HostAddress lastChosenHost =
+        primary ? haMode.lastRoundRobinPrimaryHost : haMode.lastRoundRobinSecondaryHost;
+
+    List<HostAddress> loopList;
+    if (lastChosenHost == null) {
+      loopList = hostAddresses;
+    } else {
+      int lastChosenIndex = hostAddresses.indexOf(lastChosenHost);
+      loopList = new ArrayList<>();
+      loopList.addAll(hostAddresses.subList(lastChosenIndex + 1, hostAddresses.size()));
+      loopList.addAll(hostAddresses.subList(0, lastChosenIndex + 1));
+    }
+
+    for (HostAddress hostAddress : loopList) {
+      if (hostAddress.primary == primary) {
+        if (denyList.containsKey(hostAddress)) {
+          // take in account denied server that have reached denied timeout
+          if (denyList.get(hostAddress) > System.currentTimeMillis()) {
+            continue;
+          } else {
+            denyList.remove(hostAddress);
+          }
+        }
+        if (primary) {
+          haMode.lastRoundRobinPrimaryHost = hostAddress;
+        } else {
+          haMode.lastRoundRobinSecondaryHost = hostAddress;
+        }
+        return Optional.of(hostAddress);
+      }
+    }
+    return Optional.empty();
+  }
+
+  /**
+   * List of hosts without blacklist entries, ordered according to HA mode
+   *
+   * @param hostAddresses hosts
+   * @param denyList hosts temporary denied
+   * @param primary type
+   * @return list without denied hosts
+   */
+  public abstract Optional<HostAddress> getAvailableHost(
+      List<HostAddress> hostAddresses, ConcurrentMap<HostAddress, Long> denyList, boolean primary);
+}
diff --git a/src/main/java/org/mariadb/jdbc/export/MaxAllowedPacketException.java b/src/main/java/org/mariadb/jdbc/export/MaxAllowedPacketException.java
new file mode 100644
index 0000000..253e7e9
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/export/MaxAllowedPacketException.java
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.export;
+
+import java.io.IOException;
+
+/**
+ * Dedicate exception when error is due to sending packet with size &gt; to server
+ * max_allowed_packet, that would cause server to drop connection
+ */
+public class MaxAllowedPacketException extends IOException {
+
+  private static final long serialVersionUID = 5669184960442818475L;
+  /** is connection in wrong state */
+  private final boolean mustReconnect;
+
+  /**
+   * Constructor
+   *
+   * @param message error message
+   * @param mustReconnect is connection state unsure
+   */
+  public MaxAllowedPacketException(String message, boolean mustReconnect) {
+    super(message);
+    this.mustReconnect = mustReconnect;
+  }
+
+  /**
+   * Indicate that connection state is unsure
+   *
+   * @return must driver reconnect connection
+   */
+  public boolean isMustReconnect() {
+    return mustReconnect;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/export/Prepare.java b/src/main/java/org/mariadb/jdbc/export/Prepare.java
new file mode 100644
index 0000000..bb451af
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/export/Prepare.java
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.export;
+
+import java.sql.SQLException;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.ColumnDecoder;
+
+/** Prepare packet COM_STMT_PREPARE (see https://mariadb.com/kb/en/com_stmt_prepare/) */
+public interface Prepare {
+
+  /**
+   * Close Prepared command
+   *
+   * @param con current connection
+   * @throws SQLException if prepare close fails
+   */
+  void close(Client con) throws SQLException;
+
+  /**
+   * Decrement use of prepare. In case not used anymore, and not in cache, will be close.
+   *
+   * @param con connection
+   * @param preparedStatement current prepared statement that was using prepare object
+   * @throws SQLException if close fails
+   */
+  void decrementUse(Client con, ServerPreparedStatement preparedStatement) throws SQLException;
+
+  /**
+   * Get current prepare statement id
+   *
+   * @return statement id
+   */
+  int getStatementId();
+
+  /**
+   * Prepare parameters
+   *
+   * @return parameters metadata
+   */
+  ColumnDecoder[] getParameters();
+
+  /**
+   * Prepare result-set columns
+   *
+   * @return result-set columns metadata
+   */
+  ColumnDecoder[] getColumns();
+
+  /**
+   * set prepare result-set columns
+   *
+   * @param columns set result-set columns metadata
+   */
+  void setColumns(ColumnDecoder[] columns);
+}
diff --git a/src/main/java/org/mariadb/jdbc/export/SslMode.java b/src/main/java/org/mariadb/jdbc/export/SslMode.java
new file mode 100644
index 0000000..1878f19
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/export/SslMode.java
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.export;
+
+/** SSl requirement */
+public enum SslMode {
+  /** NO SSL */
+  DISABLE("disable", new String[] {"DISABLED", "0", "false"}),
+
+  /** Encryption only (no certificate and hostname validation) (DEVELOPMENT ONLY) */
+  TRUST("trust", new String[] {"REQUIRED"}),
+
+  /** Encryption, certificates validation, BUT no hostname verification */
+  VERIFY_CA("verify-ca", new String[] {"VERIFY_CA"}),
+
+  /** Standard SSL use: Encryption, certificate validation and hostname validation */
+  VERIFY_FULL("verify-full", new String[] {"VERIFY_IDENTITY", "1", "true"});
+
+  private final String value;
+  private final String[] aliases;
+
+  SslMode(String value, String[] aliases) {
+    this.value = value;
+    this.aliases = aliases;
+  }
+
+  /**
+   * Create SSLMode from enumeration value, or aliases
+   *
+   * @param value enumeration value or alias
+   * @return SSLMode if corresponding enumeration value or alias found
+   */
+  public static SslMode from(String value) {
+    for (SslMode sslMode : values()) {
+      if (sslMode.value.equalsIgnoreCase(value) || sslMode.name().equalsIgnoreCase(value)) {
+        return sslMode;
+      }
+      for (String alias : sslMode.aliases) {
+        if (alias.equalsIgnoreCase(value)) {
+          return sslMode;
+        }
+      }
+    }
+    throw new IllegalArgumentException(
+        String.format("Wrong argument value '%s' for SslMode", value));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/ClientMessage.java b/src/main/java/org/mariadb/jdbc/message/ClientMessage.java
new file mode 100644
index 0000000..f23af0c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/ClientMessage.java
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Pattern;
+import org.mariadb.jdbc.BasePreparedStatement;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.client.result.StreamingResult;
+import org.mariadb.jdbc.client.result.UpdatableResult;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.server.ErrorPacket;
+import org.mariadb.jdbc.message.server.OkPacket;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+public interface ClientMessage {
+
+  /**
+   * Encode client message to socket.
+   *
+   * @param writer socket writer
+   * @param context connection context
+   * @return number of client message written
+   * @throws IOException if socket error occur
+   * @throws SQLException if any issue occurs
+   */
+  int encode(Writer writer, Context context) throws IOException, SQLException;
+
+  /**
+   * Number of parameter rows, and so expected return length
+   *
+   * @return batch update length
+   */
+  default int batchUpdateLength() {
+    return 0;
+  }
+
+  /**
+   * Message description
+   *
+   * @return description
+   */
+  default String description() {
+    return null;
+  }
+
+  /**
+   * Are return value encoded in binary protocol
+   *
+   * @return use binary protocol
+   */
+  default boolean binaryProtocol() {
+    return false;
+  }
+
+  /**
+   * Can skip metadata
+   *
+   * @return can skip metadata
+   */
+  default boolean canSkipMeta() {
+    return false;
+  }
+
+  /**
+   * default packet resultset parser
+   *
+   * @param stmt caller
+   * @param fetchSize fetch size
+   * @param maxRows maximum number of rows
+   * @param resultSetConcurrency resultset concurrency
+   * @param resultSetType resultset type
+   * @param closeOnCompletion must close caller on result parsing end
+   * @param reader packet reader
+   * @param writer packet writer
+   * @param context connection context
+   * @param exceptionFactory connection exception factory
+   * @param lock thread safe locks
+   * @param traceEnable is logging trace enable
+   * @param message client message
+   * @return results
+   * @throws IOException if any socket error occurs
+   * @throws SQLException for other kind of errors
+   */
+  default Completion readPacket(
+      Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      Reader reader,
+      Writer writer,
+      Context context,
+      ExceptionFactory exceptionFactory,
+      ReentrantLock lock,
+      boolean traceEnable,
+      ClientMessage message)
+      throws IOException, SQLException {
+
+    ReadableByteBuf buf = reader.readReusablePacket(traceEnable);
+
+    switch (buf.getByte()) {
+
+        // *********************************************************************************************************
+        // * OK response
+        // *********************************************************************************************************
+      case (byte) 0x00:
+        return new OkPacket(buf, context);
+
+        // *********************************************************************************************************
+        // * ERROR response
+        // *********************************************************************************************************
+      case (byte) 0xff:
+        // force current status to in transaction to ensure rollback/commit, since command may
+        // have issue a transaction
+        ErrorPacket errorPacket = new ErrorPacket(buf, context);
+        throw exceptionFactory
+            .withSql(this.description())
+            .create(
+                errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
+      case (byte) 0xfb:
+        buf.skip(1); // skip header
+        SQLException exception = null;
+        reader.getSequence().set((byte) 1);
+        InputStream is = getLocalInfileInputStream();
+        if (is == null) {
+          String fileName = buf.readStringNullEnd();
+          if (!message.validateLocalFileName(fileName, context)) {
+            exception =
+                exceptionFactory
+                    .withSql(this.description())
+                    .create(
+                        String.format(
+                            "LOAD DATA LOCAL INFILE asked for file '%s' that doesn't correspond to"
+                                + " initial query %s. Possible malicious proxy changing server"
+                                + " answer ! Command interrupted",
+                            fileName, this.description()),
+                        "HY000");
+          } else {
+
+            try {
+              is = new FileInputStream(fileName);
+            } catch (FileNotFoundException f) {
+              exception =
+                  exceptionFactory
+                      .withSql(this.description())
+                      .create("Could not send file : " + f.getMessage(), "HY000", f);
+            }
+          }
+        }
+
+        // sending stream
+        if (is != null) {
+          try {
+            byte[] fileBuf = new byte[8192];
+            int len;
+            while ((len = is.read(fileBuf)) > 0) {
+              writer.writeBytes(fileBuf, 0, len);
+              writer.flush();
+            }
+          } finally {
+            is.close();
+          }
+        }
+
+        // after file send / having an error, sending an empty packet to keep connection state ok
+        writer.writeEmptyPacket();
+        Completion completion =
+            readPacket(
+                stmt,
+                fetchSize,
+                maxRows,
+                resultSetConcurrency,
+                resultSetType,
+                closeOnCompletion,
+                reader,
+                writer,
+                context,
+                exceptionFactory,
+                lock,
+                traceEnable,
+                message);
+        if (exception != null) {
+          throw exception;
+        }
+        return completion;
+
+        // *********************************************************************************************************
+        // * ResultSet
+        // *********************************************************************************************************
+      default:
+        int fieldCount = buf.readIntLengthEncodedNotNull();
+
+        ColumnDecoder[] ci;
+        boolean canSkipMeta = context.canSkipMeta() && this.canSkipMeta();
+        boolean skipMeta = canSkipMeta ? buf.readByte() == 0 : false;
+        if (canSkipMeta && skipMeta) {
+          ci = ((BasePreparedStatement) stmt).getMeta();
+        } else {
+          // read columns information's
+          ci = new ColumnDecoder[fieldCount];
+          for (int i = 0; i < fieldCount; i++) {
+            ci[i] =
+                ColumnDecoder.decode(
+                    new StandardReadableByteBuf(reader.readPacket(traceEnable)),
+                    context.isExtendedInfo());
+          }
+        }
+        if (canSkipMeta && !skipMeta) ((BasePreparedStatement) stmt).updateMeta(ci);
+
+        // intermediate EOF
+        if (!context.isEofDeprecated()) {
+          reader.skipPacket();
+        }
+
+        // read resultSet
+        if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) {
+          return new UpdatableResult(
+              stmt,
+              binaryProtocol(),
+              maxRows,
+              ci,
+              reader,
+              context,
+              resultSetType,
+              closeOnCompletion,
+              traceEnable);
+        }
+
+        if (fetchSize != 0) {
+          if ((context.getServerStatus() & ServerStatus.MORE_RESULTS_EXISTS) > 0) {
+            context.setServerStatus(context.getServerStatus() - ServerStatus.MORE_RESULTS_EXISTS);
+          }
+
+          return new StreamingResult(
+              stmt,
+              binaryProtocol(),
+              maxRows,
+              ci,
+              reader,
+              context,
+              fetchSize,
+              lock,
+              resultSetType,
+              closeOnCompletion,
+              traceEnable);
+        } else {
+          return new CompleteResult(
+              stmt,
+              binaryProtocol(),
+              maxRows,
+              ci,
+              reader,
+              context,
+              resultSetType,
+              closeOnCompletion,
+              traceEnable);
+        }
+    }
+  }
+
+  /**
+   * Get current local infile input stream.
+   *
+   * @return default to null
+   */
+  default InputStream getLocalInfileInputStream() {
+    return null;
+  }
+
+  /**
+   * Request for local file to be validated from current query.
+   *
+   * @param fileName server file request path
+   * @param context current connection context
+   * @return true if file name correspond to demand and query is a load local infile
+   */
+  default boolean validateLocalFileName(String fileName, Context context) {
+    return false;
+  }
+
+  /**
+   * Check that file requested correspond to request.
+   *
+   * @param sql current command sql
+   * @param parameters current command parameter
+   * @param fileName file path request
+   * @param context current connection context
+   * @return true if file name correspond to demand and query is a load local infile
+   */
+  static boolean validateLocalFileName(
+      String sql, Parameters parameters, String fileName, Context context) {
+    Pattern pattern =
+        Pattern.compile(
+            "^(\\s*\\/\\*([^\\*]|\\*[^\\/])*\\*\\/)*\\s*LOAD\\s+(DATA|XML)\\s+((LOW_PRIORITY|CONCURRENT)\\s+)?LOCAL\\s+INFILE\\s+'"
+                + fileName
+                + "'",
+            Pattern.CASE_INSENSITIVE);
+    if (pattern.matcher(sql).find()) {
+      return true;
+    }
+
+    if (parameters != null) {
+      pattern =
+          Pattern.compile(
+              "^(\\s*\\/\\*([^\\*]|\\*[^\\/])*\\*\\/)*\\s*LOAD\\s+(DATA|XML)\\s+((LOW_PRIORITY|CONCURRENT)\\s+)?LOCAL\\s+INFILE\\s+\\?",
+              Pattern.CASE_INSENSITIVE);
+      if (pattern.matcher(sql).find() && parameters.size() > 0) {
+        String paramString = parameters.get(0).bestEffortStringValue(context);
+        if (paramString != null) {
+          return paramString.toLowerCase().equals("'" + fileName.toLowerCase() + "'");
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/ServerMessage.java b/src/main/java/org/mariadb/jdbc/message/ServerMessage.java
new file mode 100644
index 0000000..ad40b11
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/ServerMessage.java
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message;
+
+public interface ServerMessage {}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/AuthMoreRawPacket.java b/src/main/java/org/mariadb/jdbc/message/client/AuthMoreRawPacket.java
new file mode 100644
index 0000000..3edacc0
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/AuthMoreRawPacket.java
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/** plugin additional exchanges. raw data with mysql header packet */
+public final class AuthMoreRawPacket implements ClientMessage {
+
+  private final byte[] raw;
+
+  /**
+   * Constructor
+   *
+   * @param raw plugin exchange raw data
+   */
+  public AuthMoreRawPacket(byte[] raw) {
+    this.raw = raw;
+  }
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    if (raw.length == 0) {
+      writer.writeEmptyPacket();
+    } else {
+      writer.writeBytes(raw);
+      writer.flush();
+    }
+    return 0;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/BulkExecutePacket.java b/src/main/java/org/mariadb/jdbc/message/client/BulkExecutePacket.java
new file mode 100644
index 0000000..d0a1a69
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/BulkExecutePacket.java
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.util.Parameter;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.export.MaxAllowedPacketException;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+
+/**
+ * batch execution. This relies on COM_STMT_BULK_EXECUTE see
+ * https://mariadb.com/kb/en/com_stmt_bulk_execute/
+ */
+public final class BulkExecutePacket implements RedoableWithPrepareClientMessage {
+  private List<Parameters> batchParameterList;
+  private final String command;
+  private final ServerPreparedStatement prep;
+  private Prepare prepareResult;
+
+  /**
+   * Constructor
+   *
+   * @param prepareResult prepare result
+   * @param batchParameterList batch parameter list
+   * @param command sql command
+   * @param prep object creator
+   */
+  public BulkExecutePacket(
+      Prepare prepareResult,
+      List<Parameters> batchParameterList,
+      String command,
+      ServerPreparedStatement prep) {
+    this.batchParameterList = batchParameterList;
+    this.prepareResult = prepareResult;
+    this.command = command;
+    this.prep = prep;
+  }
+
+  public void saveParameters() {
+    List<Parameters> savedList = new ArrayList<>(batchParameterList.size());
+    for (Parameters parameterList : batchParameterList) {
+      savedList.add(parameterList.clone());
+    }
+    this.batchParameterList = savedList;
+  }
+
+  public int encode(Writer writer, Context context, Prepare newPrepareResult)
+      throws IOException, SQLException {
+
+    int statementId =
+        (newPrepareResult != null && newPrepareResult.getStatementId() != -1)
+            ? newPrepareResult.getStatementId()
+            : (this.prepareResult != null ? this.prepareResult.getStatementId() : -1);
+
+    Iterator<Parameters> paramIterator = batchParameterList.iterator();
+    Parameters parameters = paramIterator.next();
+    int parameterCount = parameters.size();
+
+    @SuppressWarnings("rawtypes")
+    Parameter[] parameterHeaderType = new Parameter[parameterCount];
+    // set header type
+    for (int i = 0; i < parameterCount; i++) {
+      parameterHeaderType[i] = parameters.get(i);
+    }
+    byte[] lastCmdData = null;
+    int bulkPacketNo = 0;
+
+    // Implementation After writing a bunch of parameter to buffer is marked. then : - when writing
+    // next bunch of parameter, if buffer grow more than max_allowed_packet, send buffer up to mark,
+    // then create a new packet with current bunch of data - if a bunch of parameter data type
+    // changes
+    // send buffer up to mark, then create a new packet with new data type.
+    // Problem remains if a bunch of parameter is bigger than max_allowed_packet
+    main_loop:
+    while (true) {
+      bulkPacketNo++;
+
+      writer.initPacket();
+      writer.writeByte(0xfa); // COM_STMT_BULK_EXECUTE
+      writer.writeInt(statementId);
+      writer.writeShort((short) 128); // always SEND_TYPES_TO_SERVER
+
+      for (int i = 0; i < parameterCount; i++) {
+        writer.writeShort((short) parameterHeaderType[i].getBinaryEncodeType());
+      }
+
+      if (lastCmdData != null) {
+        if (writer.throwMaxAllowedLength(lastCmdData.length)) {
+          throw new MaxAllowedPacketException(
+              "query size is >= to max_allowed_packet", writer.getCmdLength() != 0);
+        }
+        writer.writeBytes(lastCmdData);
+        writer.mark();
+        lastCmdData = null;
+        if (!paramIterator.hasNext()) {
+          break;
+        }
+        parameters = paramIterator.next();
+      }
+
+      parameter_loop:
+      while (true) {
+        for (int i = 0; i < parameterCount; i++) {
+          Parameter param = parameters.get(i);
+          if (param.isNull()) {
+            writer.writeByte(0x01); // value is null
+          } else {
+            writer.writeByte(0x00); // value follow
+            param.encodeBinary(writer);
+          }
+        }
+
+        if (!writer.isMarked() && writer.hasFlushed()) {
+          // parameter were too big to fit in a MySQL packet
+          // need to finish the packet separately
+          writer.flush();
+          if (!paramIterator.hasNext()) {
+            break main_loop;
+          }
+          parameters = paramIterator.next();
+          // reset header type
+          for (int j = 0; j < parameterCount; j++) {
+            parameterHeaderType[j] = parameters.get(j);
+          }
+          break;
+        }
+
+        if (writer.isMarked() && writer.throwMaxAllowedLength(writer.pos())) {
+          // for max_allowed_packet < 16Mb
+          // packet length was ok at last mark, but won't with new data
+          writer.flushBufferStopAtMark();
+          writer.mark();
+          lastCmdData = writer.resetMark();
+          break;
+        }
+
+        writer.mark();
+
+        if (writer.bufIsDataAfterMark()) {
+          // flush has been done
+          lastCmdData = writer.resetMark();
+          break;
+        }
+
+        if (!paramIterator.hasNext()) {
+          break main_loop;
+        }
+
+        parameters = paramIterator.next();
+
+        // ensure type has not changed
+        for (int i = 0; i < parameterCount; i++) {
+          if (parameterHeaderType[i].getBinaryEncodeType()
+                  != parameters.get(i).getBinaryEncodeType()
+              && !parameters.get(i).isNull()) {
+            writer.flush();
+            // reset header type
+            for (int j = 0; j < parameterCount; j++) {
+              parameterHeaderType[j] = parameters.get(j);
+            }
+            break parameter_loop;
+          }
+        }
+      }
+    }
+
+    writer.flush();
+
+    return bulkPacketNo;
+  }
+
+  public int batchUpdateLength() {
+    return batchParameterList.size();
+  }
+
+  public String getCommand() {
+    return command;
+  }
+
+  public ServerPreparedStatement prep() {
+    return prep;
+  }
+
+  public boolean binaryProtocol() {
+    return true;
+  }
+
+  public String description() {
+    return command;
+  }
+
+  public void setPrepareResult(PrepareResultPacket prepareResult) {
+    this.prepareResult = prepareResult;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/ChangeDbPacket.java b/src/main/java/org/mariadb/jdbc/message/client/ChangeDbPacket.java
new file mode 100644
index 0000000..c0c1e20
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/ChangeDbPacket.java
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+
+/** change database. See https://mariadb.com/kb/en/com_init_db/ protocol */
+public final class ChangeDbPacket implements RedoableClientMessage {
+
+  private final String database;
+
+  /**
+   * Constructor to encode COM_INIT_DB packet
+   *
+   * @param database database
+   */
+  public ChangeDbPacket(String database) {
+    this.database = database;
+  }
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.initPacket();
+    writer.writeByte(0x02);
+    writer.writeString(this.database);
+    writer.flush();
+    return 1;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/ClosePreparePacket.java b/src/main/java/org/mariadb/jdbc/message/client/ClosePreparePacket.java
new file mode 100644
index 0000000..ff41762
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/ClosePreparePacket.java
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/**
+ * Client mysql COM_STMT_CLOSE packet COM_STMT_CLOSE packet. See
+ * https://mariadb.com/kb/en/3-binary-protocol-prepared-statements-com_stmt_close/
+ */
+public final class ClosePreparePacket implements ClientMessage {
+
+  private final int statementId;
+
+  /**
+   * Constructor for a prepare statement id
+   *
+   * @param statementId statement identifier
+   */
+  public ClosePreparePacket(int statementId) {
+    this.statementId = statementId;
+  }
+
+  /** send packet to socket */
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.initPacket();
+    writer.writeByte(0x19);
+    writer.writeInt(statementId);
+    writer.flush();
+    return 0;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/ExecutePacket.java b/src/main/java/org/mariadb/jdbc/message/client/ExecutePacket.java
new file mode 100644
index 0000000..2975591
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/ExecutePacket.java
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLException;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.util.Parameter;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+import org.mariadb.jdbc.plugin.codec.ByteArrayCodec;
+
+/**
+ * Execute command (COM_STMT_EXECUTE) See https://mariadb.com/kb/en/com_stmt_execute/ for
+ * documentation
+ */
+public final class ExecutePacket implements RedoableWithPrepareClientMessage {
+  private Parameters parameters;
+  private final String command;
+  private final ServerPreparedStatement prep;
+  private Prepare prepareResult;
+  private InputStream localInfileInputStream;
+
+  /**
+   * Constructor
+   *
+   * @param prepareResult prepare result
+   * @param parameters parameter
+   * @param command sql command
+   * @param prep prepared statement
+   * @param localInfileInputStream local infile input stream
+   */
+  public ExecutePacket(
+      Prepare prepareResult,
+      Parameters parameters,
+      String command,
+      ServerPreparedStatement prep,
+      InputStream localInfileInputStream) {
+    this.parameters = parameters;
+    this.prepareResult = prepareResult;
+    this.command = command;
+    this.prep = prep;
+    this.localInfileInputStream = localInfileInputStream;
+  }
+
+  public void saveParameters() {
+    this.parameters = this.parameters.clone();
+  }
+
+  @Override
+  public void ensureReplayable(Context context) throws IOException, SQLException {
+    int parameterCount = parameters.size();
+    for (int i = 0; i < parameterCount; i++) {
+      Parameter p = parameters.get(i);
+      if (!p.isNull() && p.canEncodeLongData()) {
+        this.parameters.set(
+            i, new org.mariadb.jdbc.codec.Parameter<>(ByteArrayCodec.INSTANCE, p.encodeData()));
+      }
+    }
+  }
+
+  public int encode(Writer writer, Context context, Prepare newPrepareResult)
+      throws IOException, SQLException {
+
+    int statementId =
+        (newPrepareResult != null && newPrepareResult.getStatementId() != -1)
+            ? newPrepareResult.getStatementId()
+            : (this.prepareResult != null ? this.prepareResult.getStatementId() : -1);
+
+    int parameterCount = parameters.size();
+
+    // send long data value in separate packet
+    for (int i = 0; i < parameterCount; i++) {
+      Parameter p = parameters.get(i);
+      if (!p.isNull() && p.canEncodeLongData()) {
+        new LongDataPacket(statementId, p, i).encode(writer, context);
+      }
+    }
+
+    writer.initPacket();
+    writer.writeByte(0x17);
+    writer.writeInt(statementId);
+    writer.writeByte(0x00); // NO CURSOR
+    writer.writeInt(1); // Iteration pos
+
+    if (parameterCount > 0) {
+
+      // create null bitmap and reserve place in writer
+      int nullCount = (parameterCount + 7) / 8;
+      byte[] nullBitsBuffer = new byte[nullCount];
+      int initialPos = writer.pos();
+      writer.pos(initialPos + nullCount);
+
+      // Send Parameter type flag
+      writer.writeByte(0x01);
+
+      // Store types of parameters in first package that is sent to the server.
+      for (int i = 0; i < parameterCount; i++) {
+        Parameter p = parameters.get(i);
+        writer.writeByte(p.getBinaryEncodeType());
+        writer.writeByte(0);
+        if (p.isNull()) {
+          nullBitsBuffer[i / 8] |= (1 << (i % 8));
+        }
+      }
+
+      // write nullBitsBuffer in reserved place
+      writer.writeBytesAtPos(nullBitsBuffer, initialPos);
+
+      // send not null parameter, not long data
+      for (int i = 0; i < parameterCount; i++) {
+        Parameter p = parameters.get(i);
+        if (!p.isNull() && !p.canEncodeLongData()) {
+          p.encodeBinary(writer);
+        }
+      }
+    }
+
+    writer.flush();
+    return 1;
+  }
+
+  public boolean canSkipMeta() {
+    return true;
+  }
+
+  public int batchUpdateLength() {
+    return 1;
+  }
+
+  public String getCommand() {
+    return command;
+  }
+
+  public InputStream getLocalInfileInputStream() {
+    return localInfileInputStream;
+  }
+
+  public ServerPreparedStatement prep() {
+    return prep;
+  }
+
+  public boolean binaryProtocol() {
+    return true;
+  }
+
+  public String description() {
+    return "EXECUTE " + command;
+  }
+
+  public boolean validateLocalFileName(String fileName, Context context) {
+    return ClientMessage.validateLocalFileName(command, parameters, fileName, context);
+  }
+
+  public void setPrepareResult(PrepareResultPacket prepareResult) {
+    this.prepareResult = prepareResult;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/HandshakeResponse.java b/src/main/java/org/mariadb/jdbc/message/client/HandshakeResponse.java
new file mode 100644
index 0000000..d0a406e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/HandshakeResponse.java
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import static org.mariadb.jdbc.util.constants.Capabilities.*;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.StringTokenizer;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.socket.impl.PacketWriter;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.plugin.Credential;
+import org.mariadb.jdbc.plugin.authentication.standard.NativePasswordPlugin;
+import org.mariadb.jdbc.util.VersionFactory;
+
+/**
+ * Server handshake response builder. see
+ * https://mariadb.com/kb/en/connection/#client-handshake-response
+ */
+public final class HandshakeResponse implements ClientMessage {
+
+  private static final String _CLIENT_NAME = "_client_name";
+  private static final String _CLIENT_VERSION = "_client_version";
+  private static final String _SERVER_HOST = "_server_host";
+  private static final String _OS = "_os";
+  private static final String _THREAD = "_thread";
+  private static final String _JAVA_VENDOR = "_java_vendor";
+  private static final String _JAVA_VERSION = "_java_version";
+
+  private final String username;
+  private final CharSequence password;
+  private final String database;
+  private final String connectionAttributes;
+  private final String host;
+  private final long clientCapabilities;
+  private final byte exchangeCharset;
+  private final byte[] seed;
+  private String authenticationPluginType;
+
+  /**
+   * Object with parsed results
+   *
+   * @param credential credential
+   * @param authenticationPluginType authentication plugin to use
+   * @param seed server seed
+   * @param conf configuration
+   * @param host current host
+   * @param clientCapabilities client capabilities
+   * @param exchangeCharset connection charset
+   */
+  public HandshakeResponse(
+      Credential credential,
+      String authenticationPluginType,
+      byte[] seed,
+      Configuration conf,
+      String host,
+      long clientCapabilities,
+      byte exchangeCharset) {
+    this.authenticationPluginType = authenticationPluginType;
+    this.seed = seed;
+    this.username = credential.getUser();
+    this.password = credential.getPassword();
+    this.database = conf.database();
+    this.connectionAttributes = conf.connectionAttributes();
+    this.host = host;
+    this.clientCapabilities = clientCapabilities;
+    this.exchangeCharset = exchangeCharset;
+  }
+
+  private static void writeStringLengthAscii(Writer encoder, String value) throws IOException {
+    byte[] valBytes = value.getBytes(StandardCharsets.US_ASCII);
+    encoder.writeLength(valBytes.length);
+    encoder.writeBytes(valBytes);
+  }
+
+  private static void writeStringLength(Writer encoder, String value) throws IOException {
+    byte[] valBytes = value.getBytes(StandardCharsets.UTF_8);
+    encoder.writeLength(valBytes.length);
+    encoder.writeBytes(valBytes);
+  }
+
+  private static void writeConnectAttributes(
+      Writer writer, String connectionAttributes, String host) throws IOException {
+
+    PacketWriter tmpWriter = new PacketWriter(null, 0, 0, null, null);
+    tmpWriter.pos(0);
+    writeStringLengthAscii(tmpWriter, _CLIENT_NAME);
+    writeStringLength(tmpWriter, "MariaDB Connector/J");
+
+    writeStringLengthAscii(tmpWriter, _CLIENT_VERSION);
+    writeStringLength(tmpWriter, VersionFactory.getInstance().getVersion());
+
+    writeStringLengthAscii(tmpWriter, _SERVER_HOST);
+    writeStringLength(tmpWriter, (host != null) ? host : "");
+
+    writeStringLengthAscii(tmpWriter, _OS);
+    writeStringLength(tmpWriter, System.getProperty("os.name"));
+
+    writeStringLengthAscii(tmpWriter, _THREAD);
+    writeStringLength(tmpWriter, Long.toString(Thread.currentThread().getId()));
+
+    writeStringLengthAscii(tmpWriter, _JAVA_VENDOR);
+    writeStringLength(tmpWriter, System.getProperty("java.vendor"));
+
+    writeStringLengthAscii(tmpWriter, _JAVA_VERSION);
+    writeStringLength(tmpWriter, System.getProperty("java.version"));
+
+    if (connectionAttributes != null) {
+      StringTokenizer tokenizer = new StringTokenizer(connectionAttributes, ",");
+      while (tokenizer.hasMoreTokens()) {
+        String token = tokenizer.nextToken();
+        int separator = token.indexOf(":");
+        if (separator != -1) {
+          writeStringLength(tmpWriter, token.substring(0, separator));
+          writeStringLength(tmpWriter, token.substring(separator + 1));
+        } else {
+          writeStringLength(tmpWriter, token);
+          writeStringLength(tmpWriter, "");
+        }
+      }
+    }
+
+    writer.writeLength(tmpWriter.pos());
+    writer.writeBytes(tmpWriter.buf(), 0, tmpWriter.pos());
+  }
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+
+    final byte[] authData;
+    if ("mysql_clear_password".equals(authenticationPluginType)) {
+      if (!context.hasClientCapability(SSL)) {
+        throw new IllegalStateException("Cannot send password in clear if SSL is not enabled.");
+      }
+      authData =
+          (password == null) ? new byte[0] : password.toString().getBytes(StandardCharsets.UTF_8);
+    } else {
+      authenticationPluginType = "mysql_native_password";
+      authData = NativePasswordPlugin.encryptPassword(password, seed);
+    }
+
+    writer.writeInt((int) clientCapabilities);
+    writer.writeInt(1024 * 1024 * 1024);
+    writer.writeByte(exchangeCharset); // 1
+
+    writer.writeBytes(new byte[19]); // 19
+    writer.writeInt((int) (clientCapabilities >> 32)); // Maria extended flag
+
+    writer.writeString(username != null ? username : System.getProperty("user.name"));
+    writer.writeByte(0x00);
+
+    if (context.hasServerCapability(PLUGIN_AUTH_LENENC_CLIENT_DATA)) {
+      writer.writeLength(authData.length);
+      writer.writeBytes(authData);
+    } else if (context.hasServerCapability(SECURE_CONNECTION)) {
+      writer.writeByte((byte) authData.length);
+      writer.writeBytes(authData);
+    } else {
+      writer.writeBytes(authData);
+      writer.writeByte(0x00);
+    }
+
+    if (context.hasClientCapability(CONNECT_WITH_DB)) {
+      writer.writeString(database);
+      writer.writeByte(0x00);
+    }
+
+    if (context.hasServerCapability(PLUGIN_AUTH)) {
+      writer.writeString(authenticationPluginType);
+      writer.writeByte(0x00);
+    }
+
+    if (context.hasServerCapability(CONNECT_ATTRS)) {
+      writeConnectAttributes(writer, connectionAttributes, host);
+    }
+    writer.flush();
+    return 1;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/LongDataPacket.java b/src/main/java/org/mariadb/jdbc/message/client/LongDataPacket.java
new file mode 100644
index 0000000..2caee04
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/LongDataPacket.java
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.util.Parameter;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/**
+ * COM_STMT_SEND_LONG_DATA
+ *
+ * <p>Permit to send ONE value in a dedicated packet. The advantage is when length is unknown, to
+ * stream easily data to socket
+ *
+ * <p>https://mariadb.com/kb/en/com_stmt_send_long_data/
+ */
+public final class LongDataPacket implements ClientMessage {
+
+  private final int statementId;
+  private final Parameter parameter;
+  private final int index;
+
+  /**
+   * Constructor
+   *
+   * @param statementId statement identifier
+   * @param parameter parameter
+   * @param index index
+   */
+  public LongDataPacket(int statementId, Parameter parameter, int index) {
+    this.statementId = statementId;
+    this.parameter = parameter;
+    this.index = index;
+  }
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException, SQLException {
+    writer.initPacket();
+    writer.writeByte(0x18);
+    writer.writeInt(statementId);
+    writer.writeShort((short) index);
+    parameter.encodeLongData(writer);
+    writer.flush();
+    return 0;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/PingPacket.java b/src/main/java/org/mariadb/jdbc/message/client/PingPacket.java
new file mode 100644
index 0000000..9504c5b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/PingPacket.java
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/** Ping packet see COM_PING (https://mariadb.com/kb/en/com_ping/) */
+public final class PingPacket implements ClientMessage {
+
+  /** default instance */
+  public static final PingPacket INSTANCE = new PingPacket();
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.initPacket();
+    writer.writeByte(0x0e);
+    writer.flush();
+    return 1;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/PrepareExecutePacket.java b/src/main/java/org/mariadb/jdbc/message/client/PrepareExecutePacket.java
new file mode 100644
index 0000000..9b8d6df
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/PrepareExecutePacket.java
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLException;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.BasePreparedStatement;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.util.Parameter;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.server.CachedPrepareResultPacket;
+import org.mariadb.jdbc.message.server.ErrorPacket;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+import org.mariadb.jdbc.plugin.codec.ByteArrayCodec;
+
+/**
+ * Send a client COM_STMT_PREPARE + COM_STMT_EXECUTE packets see
+ * https://mariadb.com/kb/en/com_stmt_prepare/
+ */
+public final class PrepareExecutePacket implements RedoableWithPrepareClientMessage {
+  private final String sql;
+  private Parameters parameters;
+  private final ServerPreparedStatement prep;
+  private PrepareResultPacket prepareResult;
+  private InputStream localInfileInputStream;
+  /**
+   * Construct prepare packet
+   *
+   * @param sql sql
+   * @param parameters parameter
+   * @param prep prepare
+   * @param localInfileInputStream local infile input stream
+   */
+  public PrepareExecutePacket(
+      String sql,
+      Parameters parameters,
+      ServerPreparedStatement prep,
+      InputStream localInfileInputStream) {
+    this.sql = sql;
+    this.parameters = parameters;
+    this.prep = prep;
+    this.localInfileInputStream = localInfileInputStream;
+    this.prepareResult = null;
+  }
+
+  @Override
+  public int encode(Writer writer, Context context, Prepare newPrepareResult)
+      throws IOException, SQLException {
+    int statementId = -1;
+    if (newPrepareResult == null) {
+
+      writer.initPacket();
+      writer.writeByte(0x16);
+      writer.writeString(this.sql);
+      writer.flushPipeline();
+    } else {
+      statementId = newPrepareResult.getStatementId();
+    }
+    int parameterCount = parameters.size();
+
+    // send long data value in separate packet
+    for (int i = 0; i < parameterCount; i++) {
+      Parameter p = parameters.get(i);
+      if (!p.isNull() && p.canEncodeLongData()) {
+        new LongDataPacket(statementId, p, i).encode(writer, context);
+      }
+    }
+
+    writer.initPacket();
+    writer.writeByte(0x17);
+    writer.writeInt(statementId);
+    writer.writeByte(0x00); // NO CURSOR
+    writer.writeInt(1); // Iteration pos
+
+    if (parameterCount > 0) {
+
+      // create null bitmap and reserve place in writer
+      int nullCount = (parameterCount + 7) / 8;
+      byte[] nullBitsBuffer = new byte[nullCount];
+      int initialPos = writer.pos();
+      writer.pos(initialPos + nullCount);
+
+      // Send Parameter type flag
+      writer.writeByte(0x01);
+
+      // Store types of parameters in first package that is sent to the server.
+      for (int i = 0; i < parameterCount; i++) {
+        Parameter p = parameters.get(i);
+        writer.writeByte(p.getBinaryEncodeType());
+        writer.writeByte(0);
+        if (p.isNull()) {
+          nullBitsBuffer[i / 8] |= (1 << (i % 8));
+        }
+      }
+
+      // write nullBitsBuffer in reserved place
+      writer.writeBytesAtPos(nullBitsBuffer, initialPos);
+
+      // send not null parameter, not long data
+      for (int i = 0; i < parameterCount; i++) {
+        Parameter p = parameters.get(i);
+        if (!p.isNull() && !p.canEncodeLongData()) {
+          p.encodeBinary(writer);
+        }
+      }
+    }
+
+    writer.flush();
+    return (newPrepareResult == null) ? 2 : 1;
+  }
+
+  @Override
+  public Completion readPacket(
+      Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      Reader reader,
+      Writer writer,
+      Context context,
+      ExceptionFactory exceptionFactory,
+      ReentrantLock lock,
+      boolean traceEnable,
+      ClientMessage message)
+      throws IOException, SQLException {
+    if (this.prepareResult == null) {
+      ReadableByteBuf buf = reader.readReusablePacket(traceEnable);
+      // *********************************************************************************************************
+      // * ERROR response
+      // *********************************************************************************************************
+      if (buf.getUnsignedByte()
+          == 0xff) { // force current status to in transaction to ensure rollback/commit, since
+        // command may
+        // have issue a transaction
+        ErrorPacket errorPacket = new ErrorPacket(buf, context);
+        throw exceptionFactory
+            .withSql(this.description())
+            .create(
+                errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
+      }
+      if (context.getConf().useServerPrepStmts()
+          && context.getConf().cachePrepStmts()
+          && sql.length() < 8192) {
+        PrepareResultPacket prepare = new CachedPrepareResultPacket(buf, reader, context);
+        PrepareResultPacket previousCached =
+            (PrepareResultPacket)
+                context
+                    .getPrepareCache()
+                    .put(
+                        sql,
+                        prepare,
+                        stmt instanceof ServerPreparedStatement
+                            ? (ServerPreparedStatement) stmt
+                            : null);
+        if (stmt != null) {
+          ((BasePreparedStatement) stmt)
+              .setPrepareResult(previousCached != null ? previousCached : prepare);
+        }
+        this.prepareResult = previousCached != null ? previousCached : prepare;
+        return this.prepareResult;
+      }
+      PrepareResultPacket prepareResult = new PrepareResultPacket(buf, reader, context);
+      if (stmt != null) {
+        ((BasePreparedStatement) stmt).setPrepareResult(prepareResult);
+      }
+      this.prepareResult = prepareResult;
+      return prepareResult;
+    } else {
+      return RedoableWithPrepareClientMessage.super.readPacket(
+          stmt,
+          fetchSize,
+          maxRows,
+          resultSetConcurrency,
+          resultSetType,
+          closeOnCompletion,
+          reader,
+          writer,
+          context,
+          exceptionFactory,
+          lock,
+          traceEnable,
+          message);
+    }
+  }
+
+  public void saveParameters() {
+    this.parameters = this.parameters.clone();
+  }
+
+  @Override
+  public void ensureReplayable(Context context) throws IOException, SQLException {
+    int parameterCount = parameters.size();
+    for (int i = 0; i < parameterCount; i++) {
+      Parameter p = parameters.get(i);
+      if (!p.isNull() && p.canEncodeLongData()) {
+        this.parameters.set(
+            i, new org.mariadb.jdbc.codec.Parameter<>(ByteArrayCodec.INSTANCE, p.encodeData()));
+      }
+    }
+  }
+
+  public boolean canSkipMeta() {
+    return true;
+  }
+
+  @Override
+  public String description() {
+    return "PREPARE + EXECUTE " + sql;
+  }
+
+  public int batchUpdateLength() {
+    return 1;
+  }
+
+  public String getCommand() {
+    return sql;
+  }
+
+  public InputStream getLocalInfileInputStream() {
+    return localInfileInputStream;
+  }
+
+  public ServerPreparedStatement prep() {
+    return prep;
+  }
+
+  public boolean binaryProtocol() {
+    return true;
+  }
+
+  public boolean validateLocalFileName(String fileName, Context context) {
+    return ClientMessage.validateLocalFileName(sql, parameters, fileName, context);
+  }
+
+  public void setPrepareResult(PrepareResultPacket prepareResult) {
+    this.prepareResult = prepareResult;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/PreparePacket.java b/src/main/java/org/mariadb/jdbc/message/client/PreparePacket.java
new file mode 100644
index 0000000..1112419
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/PreparePacket.java
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.concurrent.locks.ReentrantLock;
+import org.mariadb.jdbc.BasePreparedStatement;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.message.server.CachedPrepareResultPacket;
+import org.mariadb.jdbc.message.server.ErrorPacket;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+
+/** Send a client COM_STMT_PREPARE packet see https://mariadb.com/kb/en/com_stmt_prepare/ */
+public final class PreparePacket implements ClientMessage {
+  private final String sql;
+
+  /**
+   * Construct prepare packet
+   *
+   * @param sql sql command
+   */
+  public PreparePacket(String sql) {
+    this.sql = sql;
+  }
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.initPacket();
+    writer.writeByte(0x16);
+    writer.writeString(this.sql);
+    writer.flush();
+    return 1;
+  }
+
+  @Override
+  public Completion readPacket(
+      Statement stmt,
+      int fetchSize,
+      long maxRows,
+      int resultSetConcurrency,
+      int resultSetType,
+      boolean closeOnCompletion,
+      Reader reader,
+      Writer writer,
+      Context context,
+      ExceptionFactory exceptionFactory,
+      ReentrantLock lock,
+      boolean traceEnable,
+      ClientMessage message)
+      throws IOException, SQLException {
+
+    ReadableByteBuf buf = reader.readReusablePacket(traceEnable);
+    // *********************************************************************************************************
+    // * ERROR response
+    // *********************************************************************************************************
+    if (buf.getUnsignedByte()
+        == 0xff) { // force current status to in transaction to ensure rollback/commit, since
+      // command may
+      // have issue a transaction
+      ErrorPacket errorPacket = new ErrorPacket(buf, context);
+      throw exceptionFactory
+          .withSql(this.description())
+          .create(errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
+    }
+    if (context.getConf().useServerPrepStmts()
+        && context.getConf().cachePrepStmts()
+        && sql.length() < 8192) {
+      PrepareResultPacket prepare = new CachedPrepareResultPacket(buf, reader, context);
+      PrepareResultPacket previousCached =
+          (PrepareResultPacket)
+              context
+                  .getPrepareCache()
+                  .put(
+                      sql,
+                      prepare,
+                      stmt instanceof ServerPreparedStatement
+                          ? (ServerPreparedStatement) stmt
+                          : null);
+      if (stmt != null) {
+        ((BasePreparedStatement) stmt)
+            .setPrepareResult(previousCached != null ? previousCached : prepare);
+      }
+      return previousCached != null ? previousCached : prepare;
+    }
+    PrepareResultPacket prepareResult = new PrepareResultPacket(buf, reader, context);
+    if (stmt != null) {
+      ((BasePreparedStatement) stmt).setPrepareResult(prepareResult);
+    }
+    return prepareResult;
+  }
+
+  @Override
+  public String description() {
+    return "PREPARE " + sql;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/QueryPacket.java b/src/main/java/org/mariadb/jdbc/message/client/QueryPacket.java
new file mode 100644
index 0000000..98d2ee7
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/QueryPacket.java
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/** Query client packet COM_QUERY see https://mariadb.com/kb/en/com_query/ */
+public final class QueryPacket implements RedoableClientMessage {
+
+  private final String sql;
+  private final InputStream localInfileInputStream;
+
+  /**
+   * Constructor
+   *
+   * @param sql sql command
+   */
+  public QueryPacket(String sql) {
+    this.sql = sql;
+    this.localInfileInputStream = null;
+  }
+
+  /**
+   * Constructor with local infile input stream
+   *
+   * @param sql sql
+   * @param localInfileInputStream local infile input stream
+   */
+  public QueryPacket(String sql, InputStream localInfileInputStream) {
+    this.sql = sql;
+    this.localInfileInputStream = localInfileInputStream;
+  }
+
+  public int batchUpdateLength() {
+    return 1;
+  }
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.initPacket();
+    writer.writeByte(0x03);
+    writer.writeString(this.sql);
+    writer.flush();
+    return 1;
+  }
+
+  /**
+   * Check that command is a COMMIT command
+   *
+   * @return true if a commit command
+   */
+  public boolean isCommit() {
+    return "COMMIT".equalsIgnoreCase(sql);
+  }
+
+  public boolean validateLocalFileName(String fileName, Context context) {
+    return ClientMessage.validateLocalFileName(sql, null, fileName, context);
+  }
+
+  public InputStream getLocalInfileInputStream() {
+    return localInfileInputStream;
+  }
+
+  public String description() {
+    return sql;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/QueryWithParametersPacket.java b/src/main/java/org/mariadb/jdbc/message/client/QueryWithParametersPacket.java
new file mode 100644
index 0000000..7c76a6e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/QueryWithParametersPacket.java
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.client.util.Parameter;
+import org.mariadb.jdbc.client.util.Parameters;
+import org.mariadb.jdbc.message.ClientMessage;
+import org.mariadb.jdbc.plugin.codec.ByteArrayCodec;
+import org.mariadb.jdbc.util.ClientParser;
+
+/**
+ * Query client packet COM_QUERY see https://mariadb.com/kb/en/com_query/ same than QueryPacket, but
+ * with parameters that will be escaped
+ */
+public final class QueryWithParametersPacket implements RedoableClientMessage {
+
+  private final String preSqlCmd;
+  private final ClientParser parser;
+  private Parameters parameters;
+  private InputStream localInfileInputStream;
+
+  /**
+   * Constructor
+   *
+   * @param preSqlCmd additional pre command
+   * @param parser command parser result
+   * @param parameters parameters
+   * @param localInfileInputStream local infile input stream
+   */
+  public QueryWithParametersPacket(
+      String preSqlCmd,
+      ClientParser parser,
+      Parameters parameters,
+      InputStream localInfileInputStream) {
+    this.preSqlCmd = preSqlCmd;
+    this.parser = parser;
+    this.parameters = parameters;
+    this.localInfileInputStream = localInfileInputStream;
+  }
+
+  @Override
+  public void ensureReplayable(Context context) throws IOException, SQLException {
+    int parameterCount = parameters.size();
+    for (int i = 0; i < parameterCount; i++) {
+      Parameter p = parameters.get(i);
+      if (!p.isNull() && p.canEncodeLongData()) {
+        this.parameters.set(
+            i, new org.mariadb.jdbc.codec.Parameter<>(ByteArrayCodec.INSTANCE, p.encodeData()));
+      }
+    }
+  }
+
+  public void saveParameters() {
+    this.parameters = this.parameters.clone();
+  }
+
+  @Override
+  public int encode(Writer encoder, Context context) throws IOException, SQLException {
+    encoder.initPacket();
+    encoder.writeByte(0x03);
+    if (preSqlCmd != null) encoder.writeAscii(preSqlCmd);
+    if (parser.getParamPositions().size() == 0) {
+      encoder.writeBytes(parser.getQuery());
+    } else {
+      int pos = 0;
+      int paramPos;
+      for (int i = 0; i < parser.getParamPositions().size(); i++) {
+        paramPos = parser.getParamPositions().get(i);
+        encoder.writeBytes(parser.getQuery(), pos, paramPos - pos);
+        pos = paramPos + 1;
+        parameters.get(i).encodeText(encoder, context);
+      }
+      encoder.writeBytes(parser.getQuery(), pos, parser.getQuery().length - pos);
+    }
+    encoder.flush();
+    return 1;
+  }
+
+  public int batchUpdateLength() {
+    return 1;
+  }
+
+  public boolean validateLocalFileName(String fileName, Context context) {
+    return ClientMessage.validateLocalFileName(parser.getSql(), parameters, fileName, context);
+  }
+
+  public InputStream getLocalInfileInputStream() {
+    return localInfileInputStream;
+  }
+
+  @Override
+  public String description() {
+    return parser.getSql();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/QuitPacket.java b/src/main/java/org/mariadb/jdbc/message/client/QuitPacket.java
new file mode 100644
index 0000000..001f59c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/QuitPacket.java
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/**
+ * ending connection packet COM_QUIT proper end of a connection. see
+ * https://mariadb.com/kb/en/com_quit/
+ */
+public final class QuitPacket implements ClientMessage {
+
+  /** default instance to encode packet */
+  public static final QuitPacket INSTANCE = new QuitPacket();
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.initPacket();
+    writer.writeByte(0x01);
+    writer.flush();
+    return 0;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/RedoableClientMessage.java b/src/main/java/org/mariadb/jdbc/message/client/RedoableClientMessage.java
new file mode 100644
index 0000000..fed79a8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/RedoableClientMessage.java
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/** Client message that can be replayed */
+public interface RedoableClientMessage extends ClientMessage {
+
+  /** Save parameters of command that can be re-executed */
+  default void saveParameters() {}
+
+  /**
+   * Ensure that command can be replayed
+   *
+   * @param context connection context
+   * @throws IOException If socket error occurs
+   * @throws SQLException for other type of issue
+   */
+  default void ensureReplayable(Context context) throws IOException, SQLException {}
+
+  /**
+   * Encode command to packet
+   *
+   * @param writer socket writer
+   * @param context connection context
+   * @param newPrepareResult new prepare result if prepare has been changed
+   * @return number of send command
+   * @throws IOException if any socket error is issued
+   * @throws SQLException if any other kind of error occurs during encoding
+   */
+  default int encode(Writer writer, Context context, Prepare newPrepareResult)
+      throws IOException, SQLException {
+    return encode(writer, context);
+  }
+
+  /**
+   * re-encode command to packet
+   *
+   * @param writer socket writer
+   * @param context connection context
+   * @param newPrepareResult new prepare result if prepare has been changed
+   * @return number of send command
+   * @throws IOException if any socket error is issued
+   * @throws SQLException if any other kind of error occurs during encoding
+   */
+  default int reEncode(Writer writer, Context context, Prepare newPrepareResult)
+      throws IOException, SQLException {
+    return encode(writer, context, newPrepareResult);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/RedoableWithPrepareClientMessage.java b/src/main/java/org/mariadb/jdbc/message/client/RedoableWithPrepareClientMessage.java
new file mode 100644
index 0000000..1891e62
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/RedoableWithPrepareClientMessage.java
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+
+/** Client message that can be replayed with parameter */
+public interface RedoableWithPrepareClientMessage extends RedoableClientMessage {
+
+  /**
+   * sql command value
+   *
+   * @return sql command
+   */
+  String getCommand();
+
+  /**
+   * Server prepare statement caller
+   *
+   * @return caller
+   */
+  ServerPreparedStatement prep();
+
+  /**
+   * Default encoder caller
+   *
+   * @param writer socket writer
+   * @param context connection context
+   * @return number of command sent
+   * @throws IOException if a socket exception occurs
+   * @throws SQLException for any other kind of error
+   */
+  default int encode(Writer writer, Context context) throws IOException, SQLException {
+    return encode(writer, context, null);
+  }
+
+  /**
+   * encoder method in case of failover, passing new prepared object
+   *
+   * @param writer socket writer
+   * @param context connection context
+   * @param newPrepareResult new prepare result
+   * @return number of command sent
+   * @throws IOException if a socket exception occurs
+   * @throws SQLException for any other kind of error
+   */
+  int encode(Writer writer, Context context, Prepare newPrepareResult)
+      throws IOException, SQLException;
+
+  /**
+   * re-encoder method in case of failover, passing new prepared object
+   *
+   * @param writer socket writer
+   * @param context connection context
+   * @param newPrepareResult new prepare result
+   * @return number of command sent
+   * @throws IOException if a socket exception occurs
+   * @throws SQLException for any other kind of error
+   */
+  @Override
+  default int reEncode(Writer writer, Context context, Prepare newPrepareResult)
+      throws IOException, SQLException {
+    return encode(writer, context, newPrepareResult);
+  }
+
+  /**
+   * Set prepare result, if pipelining prepare
+   *
+   * @param prepareResult prepare results
+   */
+  void setPrepareResult(PrepareResultPacket prepareResult);
+
+  /**
+   * Force re-prepare command
+   *
+   * @param client client
+   * @throws SQLException if any error occurs
+   */
+  default void rePrepare(Client client) throws SQLException {
+    PreparePacket preparePacket = new PreparePacket(getCommand());
+    setPrepareResult(
+        (PrepareResultPacket)
+            client
+                .execute(
+                    preparePacket,
+                    prep(),
+                    0,
+                    0L,
+                    ResultSet.CONCUR_READ_ONLY,
+                    ResultSet.TYPE_FORWARD_ONLY,
+                    false,
+                    true)
+                .get(0));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/ResetPacket.java b/src/main/java/org/mariadb/jdbc/message/client/ResetPacket.java
new file mode 100644
index 0000000..372b280
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/ResetPacket.java
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/** Reset packet COM_RESET_CONNECTION see https://mariadb.com/kb/en/com_reset_connection/ */
+public final class ResetPacket implements ClientMessage {
+
+  /** default instance */
+  public static final ResetPacket INSTANCE = new ResetPacket();
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.initPacket();
+    writer.writeByte(0x1f);
+    writer.flush();
+    return 1;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/client/SslRequestPacket.java b/src/main/java/org/mariadb/jdbc/message/client/SslRequestPacket.java
new file mode 100644
index 0000000..642992a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/client/SslRequestPacket.java
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.client;
+
+import java.io.IOException;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.ClientMessage;
+
+/** SSL request packet see https://mariadb.com/kb/en/connection/#sslrequest-packet */
+public final class SslRequestPacket implements ClientMessage {
+
+  private final long clientCapabilities;
+  private final byte exchangeCharset;
+
+  /**
+   * Constructor
+   *
+   * @param clientCapabilities client capabilities
+   * @param exchangeCharset connection charset to set
+   */
+  private SslRequestPacket(long clientCapabilities, byte exchangeCharset) {
+    this.clientCapabilities = clientCapabilities;
+    this.exchangeCharset = exchangeCharset;
+  }
+
+  /**
+   * Create ssl request packet
+   *
+   * @param clientCapabilities client capabilities
+   * @param exchangeCharset connection charset
+   * @return ssl request packet
+   */
+  public static SslRequestPacket create(long clientCapabilities, byte exchangeCharset) {
+    return new SslRequestPacket(clientCapabilities, exchangeCharset);
+  }
+
+  @Override
+  public int encode(Writer writer, Context context) throws IOException {
+    writer.writeInt((int) clientCapabilities);
+    writer.writeInt(1024 * 1024 * 1024);
+    writer.writeByte(exchangeCharset); // 1 byte
+    writer.writeBytes(new byte[19]); // 19  bytes
+    writer.writeInt((int) (clientCapabilities >> 32)); // Maria extended flag
+    writer.flush();
+    return 0;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/AuthSwitchPacket.java b/src/main/java/org/mariadb/jdbc/message/server/AuthSwitchPacket.java
new file mode 100644
index 0000000..f12cb49
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/AuthSwitchPacket.java
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server;
+
+import java.util.Arrays;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.ServerMessage;
+
+/**
+ * Authentication switch packet. See
+ * https://mariadb.com/kb/en/connection/#authentication-switch-request
+ */
+public class AuthSwitchPacket implements ServerMessage {
+
+  private final String plugin;
+  private final byte[] seed;
+
+  /**
+   * Authentication switch constructor
+   *
+   * @param plugin plugin requested
+   * @param seed plugin seed
+   */
+  public AuthSwitchPacket(String plugin, byte[] seed) {
+    this.plugin = plugin;
+    this.seed = seed;
+  }
+
+  /**
+   * Decode an AUTH_SWITCH_PACKET from a MYSQL packet.
+   *
+   * @param buf packet
+   * @return Authentication switch packet.
+   */
+  public static AuthSwitchPacket decode(ReadableByteBuf buf) {
+    buf.skip(1);
+    String plugin = buf.readStringNullEnd();
+
+    byte[] seed = new byte[buf.readableBytes()];
+    buf.readBytes(seed);
+    return new AuthSwitchPacket(plugin, seed);
+  }
+
+  /**
+   * Get authentication switch plugin information
+   *
+   * @return plugin
+   */
+  public String getPlugin() {
+    return plugin;
+  }
+
+  /**
+   * Get authentication switch seed information
+   *
+   * @return seed
+   */
+  public byte[] getSeed() {
+    return seed;
+  }
+
+  /**
+   * Get truncated seed (seed without ending 0x00 byte)
+   *
+   * @param seed connection seed
+   * @return truncated seed
+   */
+  public static byte[] getTruncatedSeed(byte[] seed) {
+    return (seed.length > 0) ? Arrays.copyOfRange(seed, 0, seed.length - 1) : new byte[0];
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/CachedPrepareResultPacket.java b/src/main/java/org/mariadb/jdbc/message/server/CachedPrepareResultPacket.java
new file mode 100644
index 0000000..edf5219
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/CachedPrepareResultPacket.java
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.client.Client;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+
+/** Prepare packet result with flag indicating use */
+public final class CachedPrepareResultPacket extends PrepareResultPacket {
+
+  private final AtomicBoolean closing = new AtomicBoolean();
+  private final AtomicBoolean cached = new AtomicBoolean();
+  private final List<ServerPreparedStatement> statements = new ArrayList<>();
+
+  /**
+   * Cache prepare result with flag indicating use
+   *
+   * @param buffer prepare packet buffer
+   * @param reader packet reader
+   * @param context connection context
+   * @throws IOException if any socket error occurs
+   */
+  public CachedPrepareResultPacket(ReadableByteBuf buffer, Reader reader, Context context)
+      throws IOException {
+    super(buffer, reader, context);
+  }
+
+  /**
+   * Indicate that a prepare statement must be closed (if not in LRU cache)
+   *
+   * @param con current connection
+   * @throws SQLException if SQL
+   */
+  public void close(Client con) throws SQLException {
+    if (!cached.get() && closing.compareAndSet(false, true)) {
+      con.closePrepare(this);
+    }
+  }
+
+  public void decrementUse(Client con, ServerPreparedStatement preparedStatement)
+      throws SQLException {
+    statements.remove(preparedStatement);
+    if (statements.size() == 0 && !cached.get()) {
+      close(con);
+    }
+  }
+
+  /**
+   * Increment use of prepare statement.
+   *
+   * @param preparedStatement new statement using prepare result
+   */
+  public void incrementUse(ServerPreparedStatement preparedStatement) {
+    if (closing.get()) {
+      return;
+    }
+    if (preparedStatement != null) statements.add(preparedStatement);
+  }
+
+  /**
+   * Indicate that Prepare command is not on LRU cache anymore. closing prepare command if not used
+   *
+   * @param con current connection
+   */
+  public void unCache(Client con) {
+    cached.set(false);
+    if (statements.size() <= 0) {
+      try {
+        close(con);
+      } catch (SQLException e) {
+        // eat
+      }
+    }
+  }
+
+  /**
+   * indicate that result is in LRU cache
+   *
+   * @return true if cached
+   */
+  public boolean cache() {
+    if (closing.get()) {
+      return false;
+    }
+    return cached.compareAndSet(false, true);
+  }
+
+  /**
+   * Return prepare statement id.
+   *
+   * @return statement id
+   */
+  public int getStatementId() {
+    return statementId;
+  }
+
+  /** Resetting cache in case of failover */
+  public void reset() {
+    statementId = -1;
+    for (ServerPreparedStatement stmt : statements) {
+      stmt.reset();
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/ColumnDefinitionPacket.java b/src/main/java/org/mariadb/jdbc/message/server/ColumnDefinitionPacket.java
new file mode 100644
index 0000000..51bc56d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/ColumnDefinitionPacket.java
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server;
+
+import java.util.Objects;
+import org.mariadb.jdbc.client.Column;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.ServerMessage;
+import org.mariadb.jdbc.util.CharsetEncodingLength;
+import org.mariadb.jdbc.util.constants.ColumnFlags;
+
+/** Column metadata definition */
+public class ColumnDefinitionPacket implements Column, ServerMessage {
+
+  private final ReadableByteBuf buf;
+  /** charset */
+  protected final int charset;
+  /** column maximum length */
+  protected final long columnLength;
+  /** data type see https://mariadb.com/kb/en/result-set-packets/#field-types */
+  protected final DataType dataType;
+  /** number of decimal */
+  protected final byte decimals;
+  /** flags see https://mariadb.com/kb/en/result-set-packets/#field-details-flag */
+  private final int flags;
+  /** string offset position in buffer */
+  private final int[] stringPos;
+  /** extended type name */
+  protected final String extTypeName;
+  /** extended type format */
+  protected final String extTypeFormat;
+  /** configuration: use alias as name */
+  private boolean useAliasAsName;
+
+  /**
+   * Column definition constructor
+   *
+   * @param buf buffer
+   * @param charset charset
+   * @param columnLength maxium column length
+   * @param dataType data type
+   * @param decimals decimal length
+   * @param flags flags
+   * @param stringPos string position indexes
+   * @param extTypeName extended type name
+   * @param extTypeFormat extended type format
+   */
+  public ColumnDefinitionPacket(
+      ReadableByteBuf buf,
+      int charset,
+      long columnLength,
+      DataType dataType,
+      byte decimals,
+      int flags,
+      int[] stringPos,
+      String extTypeName,
+      String extTypeFormat) {
+    this.buf = buf;
+    this.charset = charset;
+    this.columnLength = columnLength;
+    this.dataType = dataType;
+    this.decimals = decimals;
+    this.flags = flags;
+    this.stringPos = stringPos;
+    this.extTypeName = extTypeName;
+    this.extTypeFormat = extTypeFormat;
+  }
+
+  public String getSchema() {
+    buf.pos(stringPos[0]);
+    return buf.readString(buf.readIntLengthEncodedNotNull());
+  }
+
+  public String getTableAlias() {
+    buf.pos(stringPos[1]);
+    return buf.readString(buf.readIntLengthEncodedNotNull());
+  }
+
+  public String getTable() {
+    buf.pos(stringPos[useAliasAsName ? 1 : 2]);
+    return buf.readString(buf.readIntLengthEncodedNotNull());
+  }
+
+  public String getColumnAlias() {
+    buf.pos(stringPos[3]);
+    return buf.readString(buf.readIntLengthEncodedNotNull());
+  }
+
+  public String getColumnName() {
+    buf.pos(stringPos[4]);
+    return buf.readString(buf.readIntLengthEncodedNotNull());
+  }
+
+  public long getColumnLength() {
+    return columnLength;
+  }
+
+  public DataType getType() {
+    return dataType;
+  }
+
+  public byte getDecimals() {
+    return decimals;
+  }
+
+  public boolean isSigned() {
+    return (flags & ColumnFlags.UNSIGNED) == 0;
+  }
+
+  public int getDisplaySize() {
+    if (!isBinary()
+        && (dataType == DataType.VARCHAR
+            || dataType == DataType.JSON
+            || dataType == DataType.ENUM
+            || dataType == DataType.SET
+            || dataType == DataType.VARSTRING
+            || dataType == DataType.STRING
+            || dataType == DataType.BLOB
+            || dataType == DataType.TINYBLOB
+            || dataType == DataType.MEDIUMBLOB
+            || dataType == DataType.LONGBLOB)) {
+      Integer maxWidth = CharsetEncodingLength.maxCharlen.get(charset);
+      if (maxWidth != null) return (int) (columnLength / maxWidth);
+    }
+    return (int) columnLength;
+  }
+
+  public boolean isPrimaryKey() {
+    return (this.flags & ColumnFlags.PRIMARY_KEY) > 0;
+  }
+
+  public boolean isAutoIncrement() {
+    return (this.flags & ColumnFlags.AUTO_INCREMENT) > 0;
+  }
+
+  public boolean hasDefault() {
+    return (this.flags & ColumnFlags.NO_DEFAULT_VALUE_FLAG) == 0;
+  }
+
+  // doesn't use & 128 bit filter, because char binary and varchar binary are not binary (handle
+  // like string), but have the binary flag
+  public boolean isBinary() {
+    return charset == 63;
+  }
+
+  public int getFlags() {
+    return flags;
+  }
+
+  public String getExtTypeName() {
+    return extTypeName;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    ColumnDefinitionPacket that = (ColumnDefinitionPacket) o;
+    return charset == that.charset
+        && columnLength == that.columnLength
+        && dataType == that.dataType
+        && decimals == that.decimals
+        && flags == that.flags;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(charset, columnLength, dataType, decimals, flags);
+  }
+
+  public void useAliasAsName() {
+    useAliasAsName = true;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/ErrorPacket.java b/src/main/java/org/mariadb/jdbc/message/server/ErrorPacket.java
new file mode 100644
index 0000000..965e202
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/ErrorPacket.java
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server;
+
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.message.ServerMessage;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Server Error Packet see https://mariadb.com/kb/en/err_packet/ */
+public final class ErrorPacket implements ServerMessage {
+  private static final Logger logger = Loggers.getLogger(ErrorPacket.class);
+  private final short errorCode;
+  private final String message;
+  private final String sqlState;
+
+  /**
+   * +--------------------------------------------------+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+   * +--------------------------------------------------+------------------+ | 17 00 00 01 FF 10 04
+   * 54 6F 6F 20 6D 61 6E 79 20 | .......Too many | | 63 6F 6E 6E 65 63 74 69 6F 6E 73 | connections
+   * | +--------------------------------------------------+------------------+
+   *
+   * @param buf error packet buffer
+   * @param context current context
+   */
+  public ErrorPacket(ReadableByteBuf buf, Context context) {
+    buf.skip();
+    this.errorCode = buf.readShort();
+    byte next = buf.getByte(buf.pos());
+    if (next == (byte) '#') {
+      buf.skip(); // skip '#'
+      this.sqlState = buf.readAscii(5);
+      this.message = buf.readStringEof();
+    } else {
+      // Pre-4.1 message, still can be output in newer versions (e.g. with 'Too many connections')
+      this.message = buf.readStringEof();
+      this.sqlState = "HY000";
+    }
+    if (logger.isWarnEnabled()) {
+      logger.warn("Error: {}-{}: {}", errorCode, sqlState, message);
+    }
+
+    // force current status to in transaction to ensure rollback/commit, since command may have
+    // issue a transaction
+    if (context != null) {
+      int serverStatus = context.getServerStatus();
+      serverStatus |= ServerStatus.IN_TRANSACTION;
+      context.setServerStatus(serverStatus);
+    }
+  }
+
+  /**
+   * Error code
+   *
+   * @return error code
+   */
+  public short getErrorCode() {
+    return errorCode;
+  }
+
+  /**
+   * Error message
+   *
+   * @return error message
+   */
+  public String getMessage() {
+    return message;
+  }
+
+  /**
+   * SQL State
+   *
+   * @return SQLState
+   */
+  public String getSqlState() {
+    return sqlState;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/InitialHandshakePacket.java b/src/main/java/org/mariadb/jdbc/message/server/InitialHandshakePacket.java
new file mode 100644
index 0000000..863a366
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/InitialHandshakePacket.java
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server;
+
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.ServerVersion;
+import org.mariadb.jdbc.message.ServerMessage;
+import org.mariadb.jdbc.message.server.util.ServerVersionUtility;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+/**
+ * Server initial handshake parser. see
+ * https://mariadb.com/kb/en/connection/#initial-handshake-packet
+ */
+public final class InitialHandshakePacket implements ServerMessage {
+
+  private static final String MARIADB_RPL_HACK_PREFIX = "5.5.5-";
+
+  private final long threadId;
+  private final byte[] seed;
+  private final long capabilities;
+  private final short defaultCollation;
+  private final short serverStatus;
+  private final String authenticationPluginType;
+  private final ServerVersion version;
+
+  /**
+   * parse result
+   *
+   * @param serverVersion server version
+   * @param threadId server thread id
+   * @param seed seed
+   * @param capabilities server capabilities
+   * @param defaultCollation default server collation
+   * @param serverStatus server status flags
+   * @param mariaDBServer is a mariadb server
+   * @param authenticationPluginType default authentication plugin type
+   */
+  private InitialHandshakePacket(
+      String serverVersion,
+      long threadId,
+      byte[] seed,
+      long capabilities,
+      short defaultCollation,
+      short serverStatus,
+      boolean mariaDBServer,
+      String authenticationPluginType) {
+
+    this.threadId = threadId;
+    this.seed = seed;
+    this.capabilities = capabilities;
+    this.defaultCollation = defaultCollation;
+    this.serverStatus = serverStatus;
+    this.authenticationPluginType = authenticationPluginType;
+    this.version = new ServerVersionUtility(serverVersion, mariaDBServer);
+  }
+
+  /**
+   * parsing packet
+   *
+   * @param reader packet reader
+   * @return Parsed packet
+   */
+  public static InitialHandshakePacket decode(ReadableByteBuf reader) {
+    byte protocolVersion = reader.readByte();
+    if (protocolVersion != 0x0a) {
+      throw new IllegalArgumentException(
+          String.format("Unexpected initial handshake protocol value [%s]", protocolVersion));
+    }
+
+    String serverVersion = reader.readStringNullEnd();
+    long threadId = reader.readInt();
+    final byte[] seed1 = new byte[8];
+    reader.readBytes(seed1);
+    reader.skip();
+    int serverCapabilities2FirstBytes = reader.readUnsignedShort();
+    short defaultCollation = reader.readUnsignedByte();
+    short serverStatus = reader.readShort();
+    int serverCapabilities4FirstBytes = serverCapabilities2FirstBytes + (reader.readShort() << 16);
+    int saltLength = 0;
+
+    if ((serverCapabilities4FirstBytes & Capabilities.PLUGIN_AUTH) != 0) {
+      saltLength = Math.max(12, reader.readByte() - 9);
+    } else {
+      reader.skip();
+    }
+    reader.skip(6);
+
+    // MariaDB additional capabilities.
+    // Filled only if MariaDB server 10.2+
+    long mariaDbAdditionalCapacities = reader.readInt();
+    byte[] seed;
+    if ((serverCapabilities4FirstBytes & Capabilities.SECURE_CONNECTION) != 0) {
+      final byte[] seed2;
+      if (saltLength > 0) {
+        seed2 = new byte[saltLength];
+        reader.readBytes(seed2);
+      } else {
+        seed2 = reader.readBytesNullEnd();
+      }
+      seed = new byte[seed1.length + seed2.length];
+      System.arraycopy(seed1, 0, seed, 0, seed1.length);
+      System.arraycopy(seed2, 0, seed, seed1.length, seed2.length);
+    } else {
+      seed = seed1;
+    }
+    reader.skip();
+
+    /*
+     * check for MariaDB 10.x replication hack , remove fake prefix if needed
+     *  (see comments about MARIADB_RPL_HACK_PREFIX)
+     */
+    boolean serverMariaDb;
+    if (serverVersion.startsWith(MARIADB_RPL_HACK_PREFIX)) {
+      serverMariaDb = true;
+      serverVersion = serverVersion.substring(MARIADB_RPL_HACK_PREFIX.length());
+    } else {
+      serverMariaDb = serverVersion.contains("MariaDB");
+    }
+
+    // since MariaDB 10.2
+    long serverCapabilities;
+    if ((serverCapabilities4FirstBytes & Capabilities.CLIENT_MYSQL) == 0) {
+      serverCapabilities =
+          (serverCapabilities4FirstBytes & 0xffffffffL) + (mariaDbAdditionalCapacities << 32);
+      serverMariaDb = true;
+    } else {
+      serverCapabilities = serverCapabilities4FirstBytes & 0xffffffffL;
+    }
+
+    String authenticationPluginType = null;
+    if ((serverCapabilities4FirstBytes & Capabilities.PLUGIN_AUTH) != 0) {
+      authenticationPluginType = reader.readStringNullEnd();
+    }
+
+    return new InitialHandshakePacket(
+        serverVersion,
+        threadId,
+        seed,
+        serverCapabilities,
+        defaultCollation,
+        serverStatus,
+        serverMariaDb,
+        authenticationPluginType);
+  }
+
+  /**
+   * Server Version object
+   *
+   * @return server version
+   */
+  public ServerVersion getVersion() {
+    return version;
+  }
+
+  /**
+   * Server thread id
+   *
+   * @return thread id
+   */
+  public long getThreadId() {
+    return threadId;
+  }
+
+  /**
+   * Seed for authentication plugin encryption
+   *
+   * @return seed
+   */
+  public byte[] getSeed() {
+    return seed;
+  }
+
+  /**
+   * Server capabilities
+   *
+   * @return server capabilities
+   */
+  public long getCapabilities() {
+    return capabilities;
+  }
+
+  /**
+   * Server default collation
+   *
+   * @return server default collation
+   */
+  public short getDefaultCollation() {
+    return defaultCollation;
+  }
+
+  /**
+   * Server status flags
+   *
+   * @return server status
+   */
+  public short getServerStatus() {
+    return serverStatus;
+  }
+
+  /**
+   * return authentication plugin type
+   *
+   * @return authentication plugin type
+   */
+  public String getAuthenticationPluginType() {
+    return authenticationPluginType;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/OkPacket.java b/src/main/java/org/mariadb/jdbc/message/server/OkPacket.java
new file mode 100644
index 0000000..1eff4c4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/OkPacket.java
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server;
+
+import org.mariadb.jdbc.client.Completion;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.util.constants.Capabilities;
+import org.mariadb.jdbc.util.constants.StateChange;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Ok packet parser see https://mariadb.com/kb/en/ok_packet/ */
+public class OkPacket implements Completion {
+  private static final Logger logger = Loggers.getLogger(OkPacket.class);
+
+  private final long affectedRows;
+  private final long lastInsertId;
+
+  /**
+   * Parser
+   *
+   * @param buf packet buffer
+   * @param context connection context
+   */
+  public OkPacket(ReadableByteBuf buf, Context context) {
+    buf.skip(); // ok header
+    this.affectedRows = buf.readLongLengthEncodedNotNull();
+    this.lastInsertId = buf.readLongLengthEncodedNotNull();
+    context.setServerStatus(buf.readUnsignedShort());
+    context.setWarning(buf.readUnsignedShort());
+
+    if (buf.readableBytes() > 0 && context.hasClientCapability(Capabilities.CLIENT_SESSION_TRACK)) {
+      buf.skip(buf.readIntLengthEncodedNotNull()); // skip info
+      while (buf.readableBytes() > 0) {
+        if (buf.readIntLengthEncodedNotNull() > 0) {
+          switch (buf.readByte()) {
+            case StateChange.SESSION_TRACK_SYSTEM_VARIABLES:
+              buf.readIntLengthEncodedNotNull();
+              String variable = buf.readString(buf.readIntLengthEncodedNotNull());
+              Integer len = buf.readLength();
+              String value = len == null ? null : buf.readString(len);
+              logger.debug("System variable change:  {} = {}", variable, value);
+              break;
+
+            case StateChange.SESSION_TRACK_SCHEMA:
+              buf.readIntLengthEncodedNotNull();
+              Integer dbLen = buf.readLength();
+              String database = dbLen == null ? null : buf.readString(dbLen);
+              context.setDatabase(database.isEmpty() ? null : database);
+              logger.debug("Database change: is '{}'", database);
+              break;
+
+            default:
+              buf.skip(buf.readIntLengthEncodedNotNull());
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * get affected rows
+   *
+   * @return affected rows
+   */
+  public long getAffectedRows() {
+    return affectedRows;
+  }
+
+  /**
+   * Get last auto generated insert id
+   *
+   * @return last insert id
+   */
+  public long getLastInsertId() {
+    return lastInsertId;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/PrepareResultPacket.java b/src/main/java/org/mariadb/jdbc/message/server/PrepareResultPacket.java
new file mode 100644
index 0000000..1e1b579
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/PrepareResultPacket.java
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.ServerPreparedStatement;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.export.Prepare;
+import org.mariadb.jdbc.util.constants.Capabilities;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Prepare result packet See https://mariadb.com/kb/en/com_stmt_prepare/#COM_STMT_PREPARE_OK */
+public class PrepareResultPacket implements Completion, Prepare {
+  static final ColumnDecoder CONSTANT_PARAMETER;
+
+  static {
+    byte[] bytes =
+        new byte[] {
+          0x03,
+          0x64,
+          0x65,
+          0x66,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x3F,
+          0x00,
+          0x00,
+          0x0C,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x06,
+          (byte) 0x80,
+          0x00,
+          0x00,
+          0x00,
+          0x00
+        };
+    CONSTANT_PARAMETER =
+        ColumnDecoder.decode(new StandardReadableByteBuf(bytes, bytes.length), true);
+  }
+
+  private static final Logger logger = Loggers.getLogger(PrepareResultPacket.class);
+  private final ColumnDecoder[] parameters;
+  private ColumnDecoder[] columns;
+
+  /** prepare statement id */
+  protected int statementId;
+
+  /**
+   * Prepare packet constructor (parsing)
+   *
+   * @param buffer packet buffer
+   * @param reader packet reader
+   * @param context connection context
+   * @throws IOException if socket exception occurs
+   */
+  public PrepareResultPacket(ReadableByteBuf buffer, Reader reader, Context context)
+      throws IOException {
+    boolean trace = logger.isTraceEnabled();
+    buffer.readByte(); /* skip COM_STMT_PREPARE_OK */
+    this.statementId = buffer.readInt();
+    final int numColumns = buffer.readUnsignedShort();
+    final int numParams = buffer.readUnsignedShort();
+    this.parameters = new ColumnDecoder[numParams];
+    this.columns = new ColumnDecoder[numColumns];
+
+    if (numParams > 0) {
+      for (int i = 0; i < numParams; i++) {
+        // skipping packet, since there is no metadata information.
+        // might change when https://jira.mariadb.org/browse/MDEV-15031 is done
+        parameters[i] = CONSTANT_PARAMETER;
+        reader.skipPacket();
+      }
+      if (!context.isEofDeprecated()) {
+        reader.skipPacket();
+      }
+    }
+    if (numColumns > 0) {
+      for (int i = 0; i < numColumns; i++) {
+        columns[i] =
+            ColumnDecoder.decode(
+                new StandardReadableByteBuf(reader.readPacket(trace)),
+                context.hasClientCapability(Capabilities.EXTENDED_TYPE_INFO));
+      }
+      if (!context.isEofDeprecated()) {
+        reader.skipPacket();
+      }
+    }
+  }
+
+  /**
+   * Close prepare packet
+   *
+   * @param con current connection
+   * @throws SQLException if exception occurs
+   */
+  public void close(Client con) throws SQLException {
+    con.closePrepare(this);
+  }
+
+  /**
+   * Decrement use of prepare packet, so closing it if last used
+   *
+   * @param con connection
+   * @param preparedStatement current prepared statement that was using prepare object
+   * @throws SQLException if exception occurs
+   */
+  public void decrementUse(Client con, ServerPreparedStatement preparedStatement)
+      throws SQLException {
+    close(con);
+  }
+
+  /**
+   * Get statement id
+   *
+   * @return statement id
+   */
+  public int getStatementId() {
+    return statementId;
+  }
+
+  public ColumnDecoder[] getParameters() {
+    return parameters;
+  }
+
+  public ColumnDecoder[] getColumns() {
+    return columns;
+  }
+
+  public void setColumns(ColumnDecoder[] columns) {
+    this.columns = columns;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/message/server/util/ServerVersionUtility.java b/src/main/java/org/mariadb/jdbc/message/server/util/ServerVersionUtility.java
new file mode 100644
index 0000000..8e601b0
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/message/server/util/ServerVersionUtility.java
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.message.server.util;
+
+import org.mariadb.jdbc.client.ServerVersion;
+import org.mariadb.jdbc.util.Version;
+
+/** Server version utility */
+public final class ServerVersionUtility extends Version implements ServerVersion {
+
+  private final boolean mariaDBServer;
+
+  /**
+   * Constructor
+   *
+   * @param serverVersion server version string
+   * @param mariaDBServer is server mariadb
+   */
+  public ServerVersionUtility(String serverVersion, boolean mariaDBServer) {
+    super(serverVersion);
+    this.mariaDBServer = mariaDBServer;
+  }
+
+  /**
+   * Is server mariadb
+   *
+   * @return true if server is a MariaDB server
+   */
+  public boolean isMariaDBServer() {
+    return mariaDBServer;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/AuthenticationPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/AuthenticationPlugin.java
new file mode 100644
index 0000000..a870016
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/AuthenticationPlugin.java
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+
+/** Authentication plugin descriptor */
+public interface AuthenticationPlugin {
+
+  /**
+   * Authentication plugin type.
+   *
+   * @return authentication plugin type. ex: mysql_native_password
+   */
+  String type();
+
+  /**
+   * Plugin initialization.
+   *
+   * @param authenticationData authentication data (password/token)
+   * @param seed server provided seed
+   * @param conf Connection options
+   */
+  void initialize(String authenticationData, byte[] seed, Configuration conf);
+
+  /**
+   * Process plugin authentication.
+   *
+   * @param encoder out stream
+   * @param decoder in stream
+   * @param context connection context
+   * @return response packet
+   * @throws IOException if socket error
+   * @throws SQLException if plugin exception
+   */
+  ReadableByteBuf process(Writer encoder, Reader decoder, Context context)
+      throws IOException, SQLException;
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/Codec.java b/src/main/java/org/mariadb/jdbc/plugin/Codec.java
new file mode 100644
index 0000000..8e991d8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/Codec.java
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.sql.SQLException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Writer;
+
+/**
+ * Codec interface, to describe how a certain type of data must be encoded / decoded
+ *
+ * @param <T> java type supported
+ */
+public interface Codec<T> {
+
+  /**
+   * Codec native type
+   *
+   * @return code native return type
+   */
+  String className();
+
+  /**
+   * If codec can decode this a server datatype to a java class type
+   *
+   * @param column server datatype
+   * @param type java return class
+   * @return true if codec can decode it
+   */
+  boolean canDecode(ColumnDecoder column, Class<?> type);
+
+  /**
+   * Can Codec encode the java object type
+   *
+   * @param value java object type
+   * @return true if codec can encode java type
+   */
+  boolean canEncode(Object value);
+
+  /**
+   * Decode from a mysql packet text encoded a value to codec java type
+   *
+   * @param buffer mysql packet buffer
+   * @param length encoded value length
+   * @param column server column metadata
+   * @param cal calendar
+   * @return decoded value
+   * @throws SQLDataException if unexpected error occurs during decoding
+   */
+  T decodeText(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Decode from a mysql packet binary encoded a value to codec java type
+   *
+   * @param buffer mysql packet buffer
+   * @param length encoded value length
+   * @param column server column metadata
+   * @param cal calendar
+   * @return decoded value
+   * @throws SQLDataException if unexpected error occurs during decoding
+   */
+  T decodeBinary(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException;
+
+  /**
+   * Text encode value to writer
+   *
+   * @param encoder writer
+   * @param context connection context
+   * @param value value to encode
+   * @param cal calendar
+   * @param length maximum value length
+   * @throws IOException if any socket error occurs
+   * @throws SQLException if encoding error occurs
+   */
+  void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long length)
+      throws IOException, SQLException;
+
+  /**
+   * Binary encode value to writer
+   *
+   * @param encoder writer
+   * @param value value to encode
+   * @param cal calendar
+   * @param length maximum value length
+   * @throws IOException if any socket error occurs
+   * @throws SQLException if encoding error occurs
+   */
+  void encodeBinary(Writer encoder, Object value, Calendar cal, Long length)
+      throws IOException, SQLException;
+
+  /**
+   * Indicate if can encode long data
+   *
+   * @return true if possible
+   */
+  default boolean canEncodeLongData() {
+    return false;
+  }
+
+  /**
+   * binary encoding value to a long data packet
+   *
+   * @param encoder writer
+   * @param value value to encode
+   * @param length maximum length value
+   * @throws IOException if any socket error occurs
+   * @throws SQLException if encoding error occurs
+   */
+  default void encodeLongData(Writer encoder, T value, Long length)
+      throws IOException, SQLException {
+    throw new SQLException("Data is not supposed to be send in COM_STMT_LONG_DATA");
+  }
+
+  /**
+   * binary encoding value to a byte[]
+   *
+   * @param value value to encode
+   * @param length maximum length value
+   * @return encoded value
+   * @throws IOException if any socket error occurs
+   * @throws SQLException if encoding error occurs
+   */
+  default byte[] encodeData(T value, Long length) throws IOException, SQLException {
+    throw new SQLException("Data is not supposed to be send in COM_STMT_LONG_DATA");
+  }
+
+  /**
+   * Return server encoding data type
+   *
+   * @return server encoding data type
+   */
+  int getBinaryEncodeType();
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/Credential.java b/src/main/java/org/mariadb/jdbc/plugin/Credential.java
new file mode 100644
index 0000000..9e07e9a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/Credential.java
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin;
+
+/** basic Credential (couple of user/password) */
+public class Credential {
+  private final String password;
+  private final String user;
+
+  /**
+   * Constructor of basic credential
+   *
+   * @param user user
+   * @param password password
+   */
+  public Credential(String user, String password) {
+    this.user = user;
+    this.password = password;
+  }
+
+  /**
+   * Get user
+   *
+   * @return user
+   */
+  public String getUser() {
+    return user;
+  }
+
+  /**
+   * Get password
+   *
+   * @return password
+   */
+  public String getPassword() {
+    return password;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/CredentialPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/CredentialPlugin.java
new file mode 100644
index 0000000..e80d20b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/CredentialPlugin.java
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin;
+
+import java.sql.SQLException;
+import java.util.function.Supplier;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+
+/** Credential plugin definition, to permit providing Credential to server */
+public interface CredentialPlugin extends Supplier<Credential> {
+  /**
+   * credential identifier
+   *
+   * @return type
+   */
+  String type();
+
+  /**
+   * Indicate if plugin must throw an error if SSL is not enabled
+   *
+   * @return if ssl is required
+   */
+  default boolean mustUseSsl() {
+    return false;
+  }
+
+  /**
+   * Indicate authentication plugin type to use for authentication
+   *
+   * @return plugin type to use for authentication, or null for default
+   */
+  default String defaultAuthenticationPluginType() {
+    return null;
+  }
+
+  /**
+   * Permit initializing plugin if overridden
+   *
+   * @param conf configuration
+   * @param userName user
+   * @param hostAddress host information
+   * @return credential plugin
+   * @throws SQLException if any error occurs
+   */
+  default CredentialPlugin initialize(Configuration conf, String userName, HostAddress hostAddress)
+      throws SQLException {
+    return this;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/TlsSocketPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/TlsSocketPlugin.java
new file mode 100644
index 0000000..6b5abaa
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/TlsSocketPlugin.java
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.sql.SQLException;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.export.ExceptionFactory;
+
+/** TLS Socket interface plugin */
+public interface TlsSocketPlugin {
+
+  /**
+   * plugin type.
+   *
+   * @return plugin type
+   */
+  String type();
+
+  /**
+   * Get socket factory.
+   *
+   * @param conf connection string option. Non-standard option are stored in `nonMappedOptions` if
+   *     any specific option is needed.
+   * @param exceptionFactory exception handler
+   * @return custom SSL socket factory
+   * @throws SQLException if socket factory configuration failed.
+   */
+  SSLSocketFactory getSocketFactory(Configuration conf, ExceptionFactory exceptionFactory)
+      throws SQLException;
+
+  /**
+   * Returns a socket layered over an existing socket negotiating the use of SSL over an existing
+   * socket.
+   *
+   * @param socket existing socket
+   * @param sslSocketFactory SSL socket factory
+   * @return SSL socket
+   * @throws IOException if any socket error occurs.
+   */
+  default SSLSocket createSocket(Socket socket, SSLSocketFactory sslSocketFactory)
+      throws IOException {
+    return (SSLSocket)
+        sslSocketFactory.createSocket(
+            socket,
+            socket.getInetAddress() == null ? null : socket.getInetAddress().getHostAddress(),
+            socket.getPort(),
+            true);
+  }
+
+  /**
+   * Host name verifier implementation.
+   *
+   * @param host hostname
+   * @param sslSession ssl session
+   * @param serverThreadId current server threadId
+   * @throws SSLException if verification fail
+   */
+  void verify(String host, SSLSession sslSession, long serverThreadId) throws SSLException;
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/AuthenticationPluginLoader.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/AuthenticationPluginLoader.java
new file mode 100644
index 0000000..0ac349a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/AuthenticationPluginLoader.java
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.ServiceLoader;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.Driver;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+
+/** permit loading authentication plugins */
+public final class AuthenticationPluginLoader {
+
+  /**
+   * Get authentication plugin from type String. Customs authentication plugin can be added
+   * implementing AuthenticationPlugin and registering new type in resources services.
+   *
+   * @param type authentication plugin type
+   * @param conf current configuration
+   * @return Authentication plugin corresponding to type
+   * @throws SQLException if no authentication plugin in classpath have indicated type
+   */
+  public static AuthenticationPlugin get(String type, Configuration conf) throws SQLException {
+
+    ServiceLoader<AuthenticationPlugin> loader =
+        ServiceLoader.load(AuthenticationPlugin.class, Driver.class.getClassLoader());
+
+    String[] authList = (conf.restrictedAuth() != null) ? conf.restrictedAuth().split(",") : null;
+
+    for (AuthenticationPlugin implClass : loader) {
+      if (type.equals(implClass.type())) {
+        if (conf.restrictedAuth() == null || Arrays.stream(authList).anyMatch(type::contains)) {
+          return implClass;
+        } else {
+          throw new SQLException(
+              String.format(
+                  "Client restrict authentication plugin to a limited set of authentication plugin"
+                      + " and doesn't permit requested plugin ('%s'). Current list is"
+                      + " `restrictedAuth=%s`",
+                  type, conf.restrictedAuth()),
+              "08004",
+              1251);
+        }
+      }
+    }
+    throw new SQLException(
+        "Client does not support authentication protocol requested by server. "
+            + "plugin type was = '"
+            + type
+            + "'",
+        "08004",
+        1251);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/ClearPasswordPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/ClearPasswordPlugin.java
new file mode 100644
index 0000000..f24048b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/ClearPasswordPlugin.java
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.addon;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+
+/** Clear password plugin. */
+public class ClearPasswordPlugin implements AuthenticationPlugin {
+  /** plugin name */
+  public static final String TYPE = "mysql_clear_password";
+
+  private String authenticationData;
+
+  @Override
+  public String type() {
+    return TYPE;
+  }
+
+  public void initialize(String authenticationData, byte[] authData, Configuration conf) {
+    this.authenticationData = authenticationData;
+  }
+
+  /**
+   * Send password in clear text to server.
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param context context
+   * @return response packet
+   * @throws IOException if socket error
+   */
+  public ReadableByteBuf process(Writer out, Reader in, Context context) throws IOException {
+    if (authenticationData == null) {
+      out.writeEmptyPacket();
+    } else {
+      byte[] bytePwd = authenticationData.getBytes(StandardCharsets.UTF_8);
+      out.writeBytes(bytePwd);
+      out.writeByte(0);
+      out.flush();
+    }
+
+    return in.readReusablePacket();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/SendGssApiAuthPacket.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/SendGssApiAuthPacket.java
new file mode 100644
index 0000000..ac44788
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/SendGssApiAuthPacket.java
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.addon;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+import org.mariadb.jdbc.plugin.authentication.addon.gssapi.GssUtility;
+import org.mariadb.jdbc.plugin.authentication.addon.gssapi.GssapiAuth;
+import org.mariadb.jdbc.plugin.authentication.addon.gssapi.StandardGssapiAuthentication;
+
+/** GSSAPI plugin */
+public class SendGssApiAuthPacket implements AuthenticationPlugin {
+
+  private static final GssapiAuth gssapiAuth;
+
+  static {
+    GssapiAuth init;
+    try {
+      init = GssUtility.getAuthenticationMethod();
+    } catch (Throwable t) {
+      init = new StandardGssapiAuthentication();
+    }
+    gssapiAuth = init;
+  }
+
+  private byte[] seed;
+  private String optionServicePrincipalName;
+
+  @Override
+  public String type() {
+    return "auth_gssapi_client";
+  }
+
+  /**
+   * Initialization.
+   *
+   * @param authenticationData authentication data (password/token)
+   * @param seed server provided seed
+   * @param conf Connection string options
+   */
+  public void initialize(String authenticationData, byte[] seed, Configuration conf) {
+    this.seed = seed;
+    this.optionServicePrincipalName = conf.servicePrincipalName();
+  }
+
+  /**
+   * Process gssapi plugin authentication. see
+   * https://mariadb.com/kb/en/library/authentication-plugin-gssapi/
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param context context
+   * @return response packet
+   * @throws IOException if socket error
+   * @throws SQLException if plugin exception
+   */
+  public ReadableByteBuf process(Writer out, Reader in, Context context)
+      throws IOException, SQLException {
+    ReadableByteBuf buf = new StandardReadableByteBuf(seed, seed.length);
+
+    final String serverSpn = buf.readStringNullEnd();
+    // using provided connection string SPN if set, or if not, using to server information
+    final String servicePrincipalName =
+        (optionServicePrincipalName != null) ? optionServicePrincipalName : serverSpn;
+    String mechanisms = buf.readStringNullEnd();
+    if (mechanisms.isEmpty()) {
+      mechanisms = "Kerberos";
+    }
+
+    gssapiAuth.authenticate(out, in, servicePrincipalName, mechanisms);
+
+    return in.readReusablePacket();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/GssUtility.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/GssUtility.java
new file mode 100644
index 0000000..1b6d3f5
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/GssUtility.java
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.addon.gssapi;
+
+import com.sun.jna.Platform;
+
+/** GSSAPI utility */
+public class GssUtility {
+
+  /**
+   * Get authentication method according to classpath. Windows native authentication is using
+   * Waffle-jna.
+   *
+   * @return authentication method
+   */
+  public static GssapiAuth getAuthenticationMethod() {
+    try {
+      // Waffle-jna has jna as dependency, so if not available on classpath, just use standard
+      // authentication
+      if (Platform.isWindows()) {
+        try {
+          Class.forName("waffle.windows.auth.impl.WindowsAuthProviderImpl");
+          return new WindowsNativeSspiAuthentication();
+        } catch (ClassNotFoundException cle) {
+          // waffle not in the classpath
+        }
+      }
+    } catch (Throwable cle) {
+      // jna jar's are not in classpath
+    }
+    return new StandardGssapiAuthentication();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/GssapiAuth.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/GssapiAuth.java
new file mode 100644
index 0000000..e6e906c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/GssapiAuth.java
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.addon.gssapi;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+
+/** GSSAPI interface */
+public interface GssapiAuth {
+
+  /**
+   * Authenticate
+   *
+   * @param writer socket writer
+   * @param in socket reader
+   * @param servicePrincipalName SPN
+   * @param mechanisms mechanisms
+   * @throws IOException if any socket error occurs
+   * @throws SQLException for any other type of errors
+   */
+  void authenticate(Writer writer, Reader in, String servicePrincipalName, String mechanisms)
+      throws IOException, SQLException;
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/StandardGssapiAuthentication.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/StandardGssapiAuthentication.java
new file mode 100644
index 0000000..0b32a1a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/StandardGssapiAuthentication.java
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.addon.gssapi;
+
+import java.io.*;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.sql.SQLException;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import org.ietf.jgss.*;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+
+/** Basic GSSAPI implementation if waffle is not on classpath */
+public class StandardGssapiAuthentication implements GssapiAuth {
+
+  /**
+   * Process default GSS plugin authentication.
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param servicePrincipalName service principal name
+   * @param mechanisms gssapi mechanism
+   * @throws IOException if socket error
+   * @throws SQLException in any Exception occur
+   */
+  public void authenticate(
+      final Writer out, final Reader in, final String servicePrincipalName, String mechanisms)
+      throws SQLException, IOException {
+
+    if ("".equals(servicePrincipalName)) {
+      throw new SQLException(
+          "No principal name defined on server. Please set server variable"
+              + " \"gssapi-principal-name\" or set option \"servicePrincipalName\"",
+          "28000");
+    }
+
+    if (System.getProperty("java.security.auth.login.config") == null) {
+      final File jaasConfFile;
+      try {
+        jaasConfFile = File.createTempFile("jaas.conf", null);
+        try (PrintStream bos = new PrintStream(new FileOutputStream(jaasConfFile))) {
+          bos.print(
+              "Krb5ConnectorContext {\n"
+                  + "com.sun.security.auth.module.Krb5LoginModule required "
+                  + "useTicketCache=true "
+                  + "debug=true "
+                  + "renewTGT=true "
+                  + "doNotPrompt=true; };");
+        }
+        jaasConfFile.deleteOnExit();
+      } catch (final IOException ex) {
+        throw new UncheckedIOException(ex);
+      }
+
+      System.setProperty("java.security.auth.login.config", jaasConfFile.getCanonicalPath());
+    }
+    try {
+      LoginContext loginContext = new LoginContext("Krb5ConnectorContext");
+      // attempt authentication
+      loginContext.login();
+      final Subject mySubject = loginContext.getSubject();
+      if (!mySubject.getPrincipals().isEmpty()) {
+        try {
+          PrivilegedExceptionAction<Void> action =
+              () -> {
+                try {
+                  Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
+
+                  GSSManager manager = GSSManager.getInstance();
+                  GSSName peerName = manager.createName(servicePrincipalName, GSSName.NT_USER_NAME);
+                  GSSContext context =
+                      manager.createContext(
+                          peerName, krb5Mechanism, null, GSSContext.DEFAULT_LIFETIME);
+                  context.requestMutualAuth(true);
+
+                  byte[] inToken = new byte[0];
+                  byte[] outToken;
+
+                  while (true) {
+                    outToken = context.initSecContext(inToken, 0, inToken.length);
+
+                    // Send a token to the peer if one was generated by acceptSecContext
+                    if (outToken != null) {
+                      out.writeBytes(outToken);
+                      out.flush();
+                    }
+                    if (context.isEstablished()) {
+                      break;
+                    }
+                    ReadableByteBuf buf = in.readReusablePacket();
+                    inToken = new byte[buf.readableBytes()];
+                    buf.readBytes(inToken);
+                  }
+
+                } catch (GSSException le) {
+                  throw new SQLException("GSS-API authentication exception", "28000", 1045, le);
+                }
+                return null;
+              };
+          Subject.doAs(mySubject, action);
+        } catch (PrivilegedActionException exception) {
+          throw new SQLException("GSS-API authentication exception", "28000", 1045, exception);
+        }
+      } else {
+        throw new SQLException(
+            "GSS-API authentication exception : no credential cache not found.", "28000", 1045);
+      }
+
+    } catch (LoginException le) {
+      throw new SQLException("GSS-API authentication exception", "28000", 1045, le);
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/WindowsNativeSspiAuthentication.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/WindowsNativeSspiAuthentication.java
new file mode 100644
index 0000000..6d9c8d8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/addon/gssapi/WindowsNativeSspiAuthentication.java
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.addon.gssapi;
+
+import com.sun.jna.platform.win32.Sspi;
+import com.sun.jna.platform.win32.SspiUtil;
+import java.io.IOException;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import waffle.windows.auth.IWindowsSecurityContext;
+import waffle.windows.auth.impl.WindowsSecurityContextImpl;
+
+/** Waffle windows GSSAPI implementation */
+public class WindowsNativeSspiAuthentication implements GssapiAuth {
+
+  /**
+   * Process native windows GSS plugin authentication.
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param servicePrincipalName principal name
+   * @param mechanisms gssapi mechanism
+   * @throws IOException if socket error
+   */
+  public void authenticate(
+      final Writer out, final Reader in, final String servicePrincipalName, final String mechanisms)
+      throws IOException {
+
+    // initialize a security context on the client
+    IWindowsSecurityContext clientContext =
+        WindowsSecurityContextImpl.getCurrent(mechanisms, servicePrincipalName);
+
+    do {
+
+      // Step 1: send token to server
+      byte[] tokenForTheServerOnTheClient = clientContext.getToken();
+      if (tokenForTheServerOnTheClient != null && tokenForTheServerOnTheClient.length > 0) {
+        out.writeBytes(tokenForTheServerOnTheClient);
+        out.flush();
+      }
+      if (!clientContext.isContinue()) {
+        break;
+      }
+
+      // Step 2: read server response token
+      ReadableByteBuf buf = in.readReusablePacket();
+      byte[] tokenForTheClientOnTheServer = new byte[buf.readableBytes()];
+      buf.readBytes(tokenForTheClientOnTheServer);
+      Sspi.SecBufferDesc continueToken =
+          new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, tokenForTheClientOnTheServer);
+      clientContext.initialize(clientContext.getHandle(), continueToken, servicePrincipalName);
+
+    } while (true);
+
+    clientContext.dispose();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/CachingSha2PasswordPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/CachingSha2PasswordPlugin.java
new file mode 100644
index 0000000..75fc123
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/CachingSha2PasswordPlugin.java
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.standard;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Base64;
+import javax.crypto.Cipher;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.message.client.AuthMoreRawPacket;
+import org.mariadb.jdbc.message.server.AuthSwitchPacket;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+
+/** Mysql caching sha2 password plugin */
+public class CachingSha2PasswordPlugin implements AuthenticationPlugin {
+
+  /** plugin name */
+  public static final String TYPE = "caching_sha2_password";
+
+  private String authenticationData;
+  private byte[] seed;
+  private Configuration conf;
+
+  /**
+   * Send an SHA-2 encrypted password. encryption XOR(SHA256(password), SHA256(seed,
+   * SHA256(SHA256(password))))
+   *
+   * @param password password
+   * @param seed seed
+   * @return encrypted pwd
+   */
+  public static byte[] sha256encryptPassword(final CharSequence password, final byte[] seed) {
+    if (password == null) return new byte[0];
+    byte[] truncatedSeed = AuthSwitchPacket.getTruncatedSeed(seed);
+    try {
+      final MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
+      byte[] bytePwd = password.toString().getBytes(StandardCharsets.UTF_8);
+
+      final byte[] stage1 = messageDigest.digest(bytePwd);
+      messageDigest.reset();
+
+      final byte[] stage2 = messageDigest.digest(stage1);
+      messageDigest.reset();
+
+      messageDigest.update(stage2);
+      messageDigest.update(truncatedSeed);
+
+      final byte[] digest = messageDigest.digest();
+      final byte[] returnBytes = new byte[digest.length];
+      for (int i = 0; i < digest.length; i++) {
+        returnBytes[i] = (byte) (stage1[i] ^ digest[i]);
+      }
+      return returnBytes;
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException("Could not use SHA-256, failing", e);
+    }
+  }
+
+  @Override
+  public String type() {
+    return TYPE;
+  }
+
+  /**
+   * Initialized data.
+   *
+   * @param authenticationData authentication data (password/token)
+   * @param seed server provided seed
+   * @param conf Connection string options
+   */
+  public void initialize(String authenticationData, byte[] seed, Configuration conf) {
+    this.seed = seed;
+    this.authenticationData = authenticationData;
+    this.conf = conf;
+  }
+
+  /**
+   * Process native password plugin authentication. see
+   * https://mariadb.com/kb/en/library/authentication-plugin-mysql_native_password/
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param context connection context
+   * @return response packet
+   * @throws IOException if socket error
+   */
+  public ReadableByteBuf process(Writer out, Reader in, Context context)
+      throws IOException, SQLException {
+    byte[] fastCryptPwd = sha256encryptPassword(authenticationData, seed);
+    new AuthMoreRawPacket(fastCryptPwd).encode(out, context);
+
+    ReadableByteBuf buf = in.readReusablePacket();
+
+    switch (buf.getByte()) {
+      case (byte) 0x00:
+      case (byte) 0xFF:
+        // success or error
+        return buf;
+
+      default:
+        // fast authentication result
+        byte[] authResult = new byte[buf.readIntLengthEncodedNotNull()];
+        buf.readBytes(authResult);
+        switch (authResult[0]) {
+          case 3:
+            return in.readReusablePacket();
+          case 4:
+            if (conf.sslMode() != SslMode.DISABLE) {
+              // send clear password
+
+              byte[] bytePwd = authenticationData.getBytes();
+              byte[] nullEndedValue = new byte[bytePwd.length + 1];
+              System.arraycopy(bytePwd, 0, nullEndedValue, 0, bytePwd.length);
+              new AuthMoreRawPacket(nullEndedValue).encode(out, context);
+              out.flush();
+
+            } else {
+              // retrieve public key from configuration or from server
+              PublicKey publicKey;
+              if (conf.serverRsaPublicKeyFile() != null) {
+                if (conf.serverRsaPublicKeyFile().contains("BEGIN PUBLIC KEY")) {
+                  publicKey = generatePublicKey(conf.serverRsaPublicKeyFile().getBytes());
+                } else {
+                  publicKey = readPublicKeyFromFile(conf.serverRsaPublicKeyFile());
+                }
+              } else {
+                // read public key from socket
+                if (!conf.allowPublicKeyRetrieval()) {
+                  throw new SQLException(
+                      "RSA public key is not available client side (option serverRsaPublicKeyFile"
+                          + " not set)",
+                      "S1009");
+                }
+
+                // ask public Key Retrieval
+                out.writeByte(2);
+                out.flush();
+
+                buf = in.readReusablePacket();
+                switch (buf.getByte(0)) {
+                  case (byte) 0xFF:
+                  case (byte) 0xFE:
+                    return buf;
+
+                  default:
+                    // AuthMoreData packet
+                    buf.skip();
+                    byte[] authMoreData = new byte[buf.readableBytes()];
+                    buf.readBytes(authMoreData);
+                    publicKey = generatePublicKey(authMoreData);
+                }
+              }
+
+              byte[] cipherBytes = encrypt(publicKey, authenticationData, seed);
+              out.writeBytes(cipherBytes);
+              out.flush();
+            }
+
+            return in.readReusablePacket();
+
+          default:
+            throw new SQLException(
+                "Protocol exchange error. Expect login success or RSA login request message",
+                "S1009");
+        }
+    }
+  }
+
+  /**
+   * Read public Key from file.
+   *
+   * @param serverRsaPublicKeyFile RSA public key file
+   * @return public key
+   * @throws SQLException if having an error reading file or file content is not a public key.
+   */
+  public static PublicKey readPublicKeyFromFile(String serverRsaPublicKeyFile) throws SQLException {
+    byte[] keyBytes;
+    try {
+      keyBytes = Files.readAllBytes(Paths.get(serverRsaPublicKeyFile));
+    } catch (IOException ex) {
+      throw new SQLException(
+          "Could not read server RSA public key from file : "
+              + "serverRsaPublicKeyFile="
+              + serverRsaPublicKeyFile,
+          "S1009",
+          ex);
+    }
+    return generatePublicKey(keyBytes);
+  }
+
+  /**
+   * Read public pem key from String.
+   *
+   * @param publicKeyBytes public key bytes value
+   * @return public key
+   * @throws SQLException if key cannot be parsed
+   */
+  public static PublicKey generatePublicKey(byte[] publicKeyBytes) throws SQLException {
+    try {
+      String publicKey =
+          new String(publicKeyBytes, StandardCharsets.US_ASCII)
+              .replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|\\n?-+END PUBLIC KEY-+\\r?\\n?)", "");
+
+      byte[] keyBytes = Base64.getMimeDecoder().decode(publicKey);
+      X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
+      KeyFactory kf = KeyFactory.getInstance("RSA");
+      return kf.generatePublic(spec);
+    } catch (Exception ex) {
+      throw new SQLException("Could read server RSA public key: " + ex.getMessage(), "S1009", ex);
+    }
+  }
+
+  /**
+   * Encode password with seed and public key.
+   *
+   * @param publicKey public key
+   * @param password password
+   * @param seed seed
+   * @return encoded password
+   * @throws SQLException if cannot encode password
+   */
+  public static byte[] encrypt(PublicKey publicKey, String password, byte[] seed)
+      throws SQLException {
+
+    byte[] correctedSeed = Arrays.copyOfRange(seed, 0, seed.length - 1);
+    byte[] bytePwd = password.getBytes(StandardCharsets.UTF_8);
+
+    byte[] nullFinishedPwd = Arrays.copyOf(bytePwd, bytePwd.length + 1);
+    byte[] xorBytes = new byte[nullFinishedPwd.length];
+    int seedLength = correctedSeed.length;
+
+    for (int i = 0; i < xorBytes.length; i++) {
+      xorBytes[i] = (byte) (nullFinishedPwd[i] ^ correctedSeed[i % seedLength]);
+    }
+
+    try {
+      Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
+      cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+      return cipher.doFinal(xorBytes);
+    } catch (Exception ex) {
+      throw new SQLException(
+          "Error encoding password with public key : " + ex.getMessage(), "S1009", ex);
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/Ed25519PasswordPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/Ed25519PasswordPlugin.java
new file mode 100644
index 0000000..735921e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/Ed25519PasswordPlugin.java
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.standard;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.sql.SQLException;
+import java.util.Arrays;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.GroupElement;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ed25519.Ed25519ScalarOps;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.spec.EdDSANamedCurveTable;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.spec.EdDSAParameterSpec;
+
+/** ED25519 password plugin */
+public class Ed25519PasswordPlugin implements AuthenticationPlugin {
+
+  private String authenticationData;
+  private byte[] seed;
+
+  /**
+   * Sign password
+   *
+   * @param password password
+   * @param seed server seed
+   * @return encrypted value
+   * @throws SQLException if any error occurs
+   */
+  private static byte[] ed25519SignWithPassword(final String password, final byte[] seed)
+      throws SQLException {
+
+    try {
+      byte[] bytePwd = password.getBytes(StandardCharsets.UTF_8);
+
+      MessageDigest hash = MessageDigest.getInstance("SHA-512");
+
+      int mlen = seed.length;
+      final byte[] sm = new byte[64 + mlen];
+
+      byte[] az = hash.digest(bytePwd);
+      az[0] &= 248;
+      az[31] &= 63;
+      az[31] |= 64;
+
+      System.arraycopy(seed, 0, sm, 64, mlen);
+      System.arraycopy(az, 32, sm, 32, 32);
+
+      byte[] buff = Arrays.copyOfRange(sm, 32, 96);
+      hash.reset();
+      byte[] nonce = hash.digest(buff);
+
+      Ed25519ScalarOps scalar = new Ed25519ScalarOps();
+
+      EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("Ed25519");
+      GroupElement elementAvalue = spec.getB().scalarMultiply(az);
+      byte[] elementAarray = elementAvalue.toByteArray();
+      System.arraycopy(elementAarray, 0, sm, 32, elementAarray.length);
+
+      nonce = scalar.reduce(nonce);
+      GroupElement elementRvalue = spec.getB().scalarMultiply(nonce);
+      byte[] elementRarray = elementRvalue.toByteArray();
+      System.arraycopy(elementRarray, 0, sm, 0, elementRarray.length);
+
+      hash.reset();
+      byte[] hram = hash.digest(sm);
+      hram = scalar.reduce(hram);
+      byte[] tt = scalar.multiplyAndAdd(hram, az, nonce);
+      System.arraycopy(tt, 0, sm, 32, tt.length);
+
+      return Arrays.copyOfRange(sm, 0, 64);
+
+    } catch (NoSuchAlgorithmException e) {
+      throw new SQLException("Could not use SHA-512, failing", e);
+    }
+  }
+
+  @Override
+  public String type() {
+    return "client_ed25519";
+  }
+
+  /**
+   * Initialization.
+   *
+   * @param authenticationData authentication data (password/token)
+   * @param seed server provided seed
+   * @param conf Connection string options
+   */
+  public void initialize(String authenticationData, byte[] seed, Configuration conf) {
+    this.seed = seed;
+    this.authenticationData = authenticationData;
+  }
+
+  /**
+   * Process Ed25519 password plugin authentication. see
+   * https://mariadb.com/kb/en/library/authentication-plugin-ed25519/
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param context connection context
+   * @return response packet
+   * @throws IOException if socket error
+   */
+  public ReadableByteBuf process(Writer out, Reader in, Context context)
+      throws SQLException, IOException {
+    if (authenticationData == null) {
+      out.writeEmptyPacket();
+    } else {
+      out.writeBytes(ed25519SignWithPassword(authenticationData, seed));
+      out.flush();
+    }
+
+    return in.readReusablePacket();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/NativePasswordPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/NativePasswordPlugin.java
new file mode 100644
index 0000000..75cfa04
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/NativePasswordPlugin.java
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.standard;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.message.server.AuthSwitchPacket;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+
+/** Native password implementation */
+public class NativePasswordPlugin implements AuthenticationPlugin {
+
+  /** plugin name */
+  public static final String TYPE = "mysql_native_password";
+
+  private String authenticationData;
+  private byte[] seed;
+
+  /**
+   * Encrypts a password.
+   *
+   * <p>protocol for authentication is like this:
+   *
+   * <ul>
+   *   <li>Server sends a random array of bytes (the seed)
+   *   <li>client makes a sha1 digest of the password
+   *   <li>client hashes the output of 2
+   *   <li>client digests the seed
+   *   <li>client updates the digest with the output from 3
+   *   <li>an xor of the output of 5 and 2 is sent to server
+   *   <li>server does the same thing and verifies that the scrambled passwords match
+   * </ul>
+   *
+   * @param password the password to encrypt
+   * @param seed the seed to use
+   * @return a scrambled password
+   */
+  public static byte[] encryptPassword(final CharSequence password, final byte[] seed) {
+    try {
+      if (password == null) return new byte[0];
+
+      final MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+      byte[] bytePwd = password.toString().getBytes(StandardCharsets.UTF_8);
+
+      final byte[] stage1 = messageDigest.digest(bytePwd);
+      messageDigest.reset();
+
+      final byte[] stage2 = messageDigest.digest(stage1);
+      messageDigest.reset();
+
+      messageDigest.update(seed);
+      messageDigest.update(stage2);
+
+      final byte[] digest = messageDigest.digest();
+      final byte[] returnBytes = new byte[digest.length];
+      for (int i = 0; i < digest.length; i++) {
+        returnBytes[i] = (byte) (stage1[i] ^ digest[i]);
+      }
+      return returnBytes;
+
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException("Could not use SHA-1, failing", e);
+    }
+  }
+
+  @Override
+  public String type() {
+    return TYPE;
+  }
+
+  /**
+   * Initialized data.
+   *
+   * @param authenticationData authentication data (password/token)
+   * @param seed server provided seed
+   * @param conf Connection string options
+   */
+  public void initialize(String authenticationData, byte[] seed, Configuration conf) {
+    this.seed = seed;
+    this.authenticationData = authenticationData;
+  }
+
+  /**
+   * Process native password plugin authentication. see
+   * https://mariadb.com/kb/en/library/authentication-plugin-mysql_native_password/
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param context connection context
+   * @return response packet
+   * @throws IOException if socket error
+   */
+  public ReadableByteBuf process(Writer out, Reader in, Context context) throws IOException {
+    if (authenticationData == null) {
+      out.writeEmptyPacket();
+    } else {
+      byte[] truncatedSeed = AuthSwitchPacket.getTruncatedSeed(seed);
+      out.writeBytes(encryptPassword(authenticationData, truncatedSeed));
+      out.flush();
+    }
+
+    return in.readReusablePacket();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/SendPamAuthPacket.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/SendPamAuthPacket.java
new file mode 100644
index 0000000..e965fee
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/SendPamAuthPacket.java
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.authentication.standard;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.sql.SQLException;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Reader;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+
+/**
+ * PAM (dialog) authentication plugin. This is a multi-step exchange password. If more than one
+ * step, passwordX (password2, password3, ...) options must be set.
+ */
+public class SendPamAuthPacket implements AuthenticationPlugin {
+
+  private String authenticationData;
+  private Configuration conf;
+  private int counter = 0;
+
+  @Override
+  public String type() {
+    return "dialog";
+  }
+
+  /**
+   * Initialization.
+   *
+   * @param authenticationData authentication data (password/token)
+   * @param seed server provided seed
+   * @param conf Connection string options
+   */
+  public void initialize(String authenticationData, byte[] seed, Configuration conf) {
+    this.authenticationData = authenticationData;
+    this.conf = conf;
+  }
+
+  /**
+   * Process PAM plugin authentication. see
+   * https://mariadb.com/kb/en/library/authentication-plugin-pam/
+   *
+   * @param out out stream
+   * @param in in stream
+   * @param context connection context
+   * @return response packet
+   * @throws IOException if socket error
+   */
+  public ReadableByteBuf process(Writer out, Reader in, Context context)
+      throws SQLException, IOException {
+
+    while (true) {
+      counter++;
+      String password;
+      if (counter == 1) {
+        password = authenticationData;
+      } else {
+        if (!conf.nonMappedOptions().containsKey("password" + counter)) {
+          throw new SQLException(
+              "PAM authentication request multiple passwords, but "
+                  + "'password"
+                  + counter
+                  + "' is not set");
+        }
+        password = (String) conf.nonMappedOptions().get("password" + counter);
+      }
+
+      byte[] bytePwd = password != null ? password.getBytes(StandardCharsets.UTF_8) : new byte[0];
+      out.writeBytes(bytePwd, 0, bytePwd.length);
+      out.writeByte(0);
+      out.flush();
+
+      ReadableByteBuf buf = in.readReusablePacket();
+
+      int type = buf.getUnsignedByte();
+
+      // PAM continue until finish.
+      if (type == 0xfe // Switch Request
+          || type == 0x00 // OK_Packet
+          || type == 0xff) { // ERR_Packet
+        return buf;
+      }
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/README b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/README
new file mode 100644
index 0000000..531e22d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/README
@@ -0,0 +1,7 @@
+This plugin uses public domain ed25519 code by str4d (https://github.com/str4d/ed25519-java).
+It is "ref10" java implementation from the SUPERCOP ed25519:
+
+==============================
+MariaDB changes:
+- doesn't register ed25519 to global java providers
+- remove unused classes
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/Utils.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/Utils.java
new file mode 100644
index 0000000..650e925
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/Utils.java
@@ -0,0 +1,96 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519;
+
+/**
+ * Basic utilities for EdDSA. Not for external use, not maintained as a public API.
+ *
+ * @author str4d
+ */
+public class Utils {
+
+  /**
+   * Constant-time byte comparison.
+   *
+   * @param b a byte
+   * @param c a byte
+   * @return 1 if b and c are equal, 0 otherwise.
+   */
+  public static int equal(int b, int c) {
+    int result = 0;
+    int xor = b ^ c;
+    for (int i = 0; i < 8; i++) {
+      result |= xor >> i;
+    }
+    return (result ^ 0x01) & 0x01;
+  }
+
+  /**
+   * Constant-time byte[] comparison.
+   *
+   * @param b a byte[]
+   * @param c a byte[]
+   * @return 1 if b and c are equal, 0 otherwise.
+   */
+  public static int equal(byte[] b, byte[] c) {
+    int result = 0;
+    for (int i = 0; i < 32; i++) {
+      result |= b[i] ^ c[i];
+    }
+
+    return equal(result, 0);
+  }
+
+  /**
+   * Constant-time determine if byte is negative.
+   *
+   * @param b the byte to check.
+   * @return 1 if the byte is negative, 0 otherwise.
+   */
+  public static int negative(int b) {
+    return (b >> 8) & 1;
+  }
+
+  /**
+   * Get the i'th bit of a byte array.
+   *
+   * @param h the byte array.
+   * @param i the bit index.
+   * @return 0 or 1, the value of the i'th bit in h
+   */
+  public static int bit(byte[] h, int i) {
+    return (h[i >> 3] >> (i & 7)) & 1;
+  }
+
+  /**
+   * Converts a hex string to bytes.
+   *
+   * @param s the hex string to be converted.
+   * @return the byte[]
+   */
+  public static byte[] hexToBytes(String s) {
+    int len = s.length();
+    byte[] data = new byte[len / 2];
+    for (int i = 0; i < len; i += 2) {
+      data[i / 2] =
+          (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
+    }
+    return data;
+  }
+
+  /**
+   * Converts bytes to a hex string.
+   *
+   * @param raw the byte[] to be converted.
+   * @return the hex representation as a string.
+   */
+  public static String bytesToHex(byte[] raw) {
+    if (raw == null) {
+      return null;
+    }
+    final StringBuilder hex = new StringBuilder(2 * raw.length);
+    for (final byte b : raw) {
+      hex.append(Character.forDigit((b & 0xF0) >> 4, 16))
+          .append(Character.forDigit((b & 0x0F), 16));
+    }
+    return hex.toString();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Constants.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Constants.java
new file mode 100644
index 0000000..0b22794
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Constants.java
@@ -0,0 +1,18 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math;
+
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.Utils;
+
+final class Constants {
+  public static final byte[] ZERO =
+      Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000");
+  public static final byte[] ONE =
+      Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000");
+  public static final byte[] TWO =
+      Utils.hexToBytes("0200000000000000000000000000000000000000000000000000000000000000");
+  public static final byte[] FOUR =
+      Utils.hexToBytes("0400000000000000000000000000000000000000000000000000000000000000");
+  public static final byte[] FIVE =
+      Utils.hexToBytes("0500000000000000000000000000000000000000000000000000000000000000");
+  public static final byte[] EIGHT =
+      Utils.hexToBytes("0800000000000000000000000000000000000000000000000000000000000000");
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Curve.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Curve.java
new file mode 100644
index 0000000..049f123
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Curve.java
@@ -0,0 +1,83 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math;
+
+import java.io.Serializable;
+
+/**
+ * A twisted Edwards curve. Points on the curve satisfy $-x^2 + y^2 = 1 + d x^2y^2$
+ *
+ * @author str4d
+ */
+public class Curve implements Serializable {
+  private static final long serialVersionUID = 4578920872509827L;
+  private final Field f;
+  private final FieldElement d;
+  private final FieldElement d2;
+  private final FieldElement I;
+
+  private final GroupElement zeroP2;
+  private final GroupElement zeroP3;
+  private final GroupElement zeroP3PrecomputedDouble;
+  private final GroupElement zeroPrecomp;
+
+  public Curve(Field f, byte[] d, FieldElement I) {
+    this.f = f;
+    this.d = f.fromByteArray(d);
+    this.d2 = this.d.add(this.d);
+    this.I = I;
+
+    FieldElement zero = f.ZERO;
+    FieldElement one = f.ONE;
+    zeroP2 = GroupElement.p2(this, zero, one, one);
+    zeroP3 = GroupElement.p3(this, zero, one, one, zero, false);
+    zeroP3PrecomputedDouble = GroupElement.p3(this, zero, one, one, zero, true);
+    zeroPrecomp = GroupElement.precomp(this, one, one, zero);
+  }
+
+  public Field getField() {
+    return f;
+  }
+
+  public FieldElement getD() {
+    return d;
+  }
+
+  public FieldElement get2D() {
+    return d2;
+  }
+
+  public FieldElement getI() {
+    return I;
+  }
+
+  public GroupElement getZero(GroupElement.Representation repr) {
+    switch (repr) {
+      case P2:
+        return zeroP2;
+      case P3:
+        return zeroP3;
+      case P3PrecomputedDouble:
+        return zeroP3PrecomputedDouble;
+      case PRECOMP:
+        return zeroPrecomp;
+      default:
+        return null;
+    }
+  }
+
+  public GroupElement createPoint(byte[] P, boolean precompute) {
+    return new GroupElement(this, P, precompute);
+  }
+
+  @Override
+  public int hashCode() {
+    return f.hashCode() ^ d.hashCode() ^ I.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) return true;
+    if (!(o instanceof Curve)) return false;
+    Curve c = (Curve) o;
+    return f.equals(c.getField()) && d.equals(c.getD()) && I.equals(c.getI());
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Encoding.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Encoding.java
new file mode 100644
index 0000000..b6182f4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Encoding.java
@@ -0,0 +1,43 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math;
+
+/**
+ * Common interface for all $(b-1)$-bit encodings of elements of EdDSA finite fields.
+ *
+ * @author str4d
+ */
+public abstract class Encoding {
+  protected Field f;
+
+  public synchronized void setField(Field f) {
+    if (this.f != null) throw new IllegalStateException("already set");
+    this.f = f;
+  }
+
+  /**
+   * Encode a FieldElement in its $(b-1)$-bit encoding.
+   *
+   * @param x the FieldElement to encode
+   * @return the $(b-1)$-bit encoding of this FieldElement.
+   */
+  public abstract byte[] encode(FieldElement x);
+
+  /**
+   * Decode a FieldElement from its $(b-1)$-bit encoding. The highest bit is masked out.
+   *
+   * @param in the $(b-1)$-bit encoding of a FieldElement.
+   * @return the FieldElement represented by 'val'.
+   */
+  public abstract FieldElement decode(byte[] in);
+
+  /**
+   * From the Ed25519 paper:<br>
+   * $x$ is negative if the $(b-1)$-bit encoding of $x$ is lexicographically larger than the
+   * $(b-1)$-bit encoding of -x. If $q$ is an odd prime and the encoding is the little-endian
+   * representation of $\{0, 1,\dots, q-1\}$ then the negative elements of $F_q$ are $\{1, 3,
+   * 5,\dots, q-2\}$.
+   *
+   * @param x the FieldElement to check
+   * @return true if negative
+   */
+  public abstract boolean isNegative(FieldElement x);
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Field.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Field.java
new file mode 100644
index 0000000..2eecde6
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/Field.java
@@ -0,0 +1,72 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math;
+
+import java.io.Serializable;
+
+/**
+ * An EdDSA finite field. Includes several pre-computed values.
+ *
+ * @author str4d
+ */
+public class Field implements Serializable {
+  private static final long serialVersionUID = 8746587465875676L;
+
+  public final FieldElement ZERO;
+  public final FieldElement ONE;
+  public final FieldElement TWO;
+  public final FieldElement FOUR;
+  public final FieldElement FIVE;
+  public final FieldElement EIGHT;
+
+  private final int b;
+  private final FieldElement q;
+  /** q-2 */
+  private final FieldElement qm2;
+  /** (q-5) / 8 */
+  private final FieldElement qm5d8;
+
+  private final Encoding enc;
+
+  public Field(int b, byte[] q, Encoding enc) {
+    this.b = b;
+    this.enc = enc;
+    this.enc.setField(this);
+
+    this.q = fromByteArray(q);
+
+    // Set up constants
+    ZERO = fromByteArray(Constants.ZERO);
+    ONE = fromByteArray(Constants.ONE);
+    TWO = fromByteArray(Constants.TWO);
+    FOUR = fromByteArray(Constants.FOUR);
+    FIVE = fromByteArray(Constants.FIVE);
+    EIGHT = fromByteArray(Constants.EIGHT);
+
+    // Precompute values
+    qm2 = this.q.subtract(TWO);
+    qm5d8 = this.q.subtract(FIVE).divide(EIGHT);
+  }
+
+  public FieldElement fromByteArray(byte[] x) {
+    return enc.decode(x);
+  }
+
+  public int getb() {
+    return b;
+  }
+
+  public Encoding getEncoding() {
+    return enc;
+  }
+
+  @Override
+  public int hashCode() {
+    return q.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof Field)) return false;
+    Field f = (Field) obj;
+    return b == f.b && q.equals(f.q);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/FieldElement.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/FieldElement.java
new file mode 100644
index 0000000..3f2262e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/FieldElement.java
@@ -0,0 +1,64 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math;
+
+import java.io.Serializable;
+
+/** Note: concrete subclasses must implement hashCode() and equals() */
+public abstract class FieldElement implements Serializable {
+  private static final long serialVersionUID = 1239527465875676L;
+
+  protected final Field f;
+
+  public FieldElement(Field f) {
+    if (null == f) {
+      throw new IllegalArgumentException("field cannot be null");
+    }
+    this.f = f;
+  }
+
+  /**
+   * Encode a FieldElement in its $(b-1)$-bit encoding.
+   *
+   * @return the $(b-1)$-bit encoding of this FieldElement.
+   */
+  public byte[] toByteArray() {
+    return f.getEncoding().encode(this);
+  }
+
+  public abstract boolean isNonZero();
+
+  public boolean isNegative() {
+    return f.getEncoding().isNegative(this);
+  }
+
+  public abstract FieldElement add(FieldElement val);
+
+  public FieldElement addOne() {
+    return add(f.ONE);
+  }
+
+  public abstract FieldElement subtract(FieldElement val);
+
+  public FieldElement subtractOne() {
+    return subtract(f.ONE);
+  }
+
+  public abstract FieldElement negate();
+
+  public FieldElement divide(FieldElement val) {
+    return multiply(val.invert());
+  }
+
+  public abstract FieldElement multiply(FieldElement val);
+
+  public abstract FieldElement square();
+
+  public abstract FieldElement squareAndDouble();
+
+  public abstract FieldElement invert();
+
+  public abstract FieldElement pow22523();
+
+  public abstract FieldElement cmov(FieldElement val, final int b);
+
+  // Note: concrete subclasses must implement hashCode() and equals()
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/GroupElement.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/GroupElement.java
new file mode 100644
index 0000000..feb9ffa
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/GroupElement.java
@@ -0,0 +1,1003 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.Utils;
+
+/**
+ * A point $(x,y)$ on an EdDSA curve.
+ *
+ * <p>Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
+ *
+ * <p>Literature:<br>
+ * [1] Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe and Bo-Yin Yang : High-speed
+ * high-security signatures<br>
+ * [2] Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, Ed Dawson: Twisted Edwards Curves Revisited
+ * <br>
+ * [3] Daniel J. Bernsteina, Tanja Lange: A complete set of addition laws for incomplete Edwards
+ * curves<br>
+ * [4] Daniel J. Bernstein, Peter Birkner, Marc Joye, Tanja Lange and Christiane Peters: Twisted
+ * Edwards Curves<br>
+ * [5] Christiane Pascale Peters: Curves, Codes, and Cryptography (PhD thesis)<br>
+ * [6] Daniel J. Bernstein, Peter Birkner, Tanja Lange and Christiane Peters: Optimizing double-base
+ * elliptic-curve single-scalar multiplication<br>
+ *
+ * @author str4d
+ */
+public class GroupElement implements Serializable {
+  private static final long serialVersionUID = 2395879087349587L;
+
+  /**
+   * Available representations for a group element.
+   *
+   * <ul>
+   *   <li>P2: Projective representation $(X:Y:Z)$ satisfying $x=X/Z, y=Y/Z$.
+   *   <li>P3: Extended projective representation $(X:Y:Z:T)$ satisfying $x=X/Z, y=Y/Z, XY=ZT$.
+   *   <li>P3PrecomputedDouble: P3 but with dblPrecmp populated.
+   *   <li>P1P1: Completed representation $((X:Z), (Y:T))$ satisfying $x=X/Z, y=Y/T$.
+   *   <li>PRECOMP: Precomputed representation $(y+x, y-x, 2dxy)$.
+   *   <li>CACHED: Cached representation $(Y+X, Y-X, Z, 2dT)$
+   * </ul>
+   */
+  public enum Representation {
+    /** Projective ($P^2$): $(X:Y:Z)$ satisfying $x=X/Z, y=Y/Z$ */
+    P2,
+    /** Extended ($P^3$): $(X:Y:Z:T)$ satisfying $x=X/Z, y=Y/Z, XY=ZT$ */
+    P3,
+    /** Can only be requested. Results in P3 representation but also populates dblPrecmp. */
+    P3PrecomputedDouble,
+    /** Completed ($P \times P$): $((X:Z),(Y:T))$ satisfying $x=X/Z, y=Y/T$ */
+    P1P1,
+    /** Precomputed (Duif): $(y+x,y-x,2dxy)$ */
+    PRECOMP,
+    /** Cached: $(Y+X,Y-X,Z,2dT)$ */
+    CACHED
+  }
+
+  /**
+   * Creates a new group element in P2 representation.
+   *
+   * @param curve The curve.
+   * @param X The $X$ coordinate.
+   * @param Y The $Y$ coordinate.
+   * @param Z The $Z$ coordinate.
+   * @return The group element in P2 representation.
+   */
+  public static GroupElement p2(
+      final Curve curve, final FieldElement X, final FieldElement Y, final FieldElement Z) {
+    return new GroupElement(curve, Representation.P2, X, Y, Z, null);
+  }
+
+  /**
+   * Creates a new group element in P3 representation, without pre-computation.
+   *
+   * @param curve The curve.
+   * @param X The $X$ coordinate.
+   * @param Y The $Y$ coordinate.
+   * @param Z The $Z$ coordinate.
+   * @param T The $T$ coordinate.
+   * @return The group element in P3 representation.
+   */
+  public static GroupElement p3(
+      final Curve curve,
+      final FieldElement X,
+      final FieldElement Y,
+      final FieldElement Z,
+      final FieldElement T) {
+    return p3(curve, X, Y, Z, T, false);
+  }
+
+  /**
+   * Creates a new group element in P3 representation, potentially with pre-computation.
+   *
+   * @param curve The curve.
+   * @param X The $X$ coordinate.
+   * @param Y The $Y$ coordinate.
+   * @param Z The $Z$ coordinate.
+   * @param T The $T$ coordinate.
+   * @param precomputeDoubleOnly If true, populate dblPrecmp, else set to null.
+   * @return The group element in P3 representation.
+   */
+  public static GroupElement p3(
+      final Curve curve,
+      final FieldElement X,
+      final FieldElement Y,
+      final FieldElement Z,
+      final FieldElement T,
+      final boolean precomputeDoubleOnly) {
+    return new GroupElement(curve, Representation.P3, X, Y, Z, T, precomputeDoubleOnly);
+  }
+
+  /**
+   * Creates a new group element in P1P1 representation.
+   *
+   * @param curve The curve.
+   * @param X The $X$ coordinate.
+   * @param Y The $Y$ coordinate.
+   * @param Z The $Z$ coordinate.
+   * @param T The $T$ coordinate.
+   * @return The group element in P1P1 representation.
+   */
+  public static GroupElement p1p1(
+      final Curve curve,
+      final FieldElement X,
+      final FieldElement Y,
+      final FieldElement Z,
+      final FieldElement T) {
+    return new GroupElement(curve, Representation.P1P1, X, Y, Z, T);
+  }
+
+  /**
+   * Creates a new group element in PRECOMP representation.
+   *
+   * @param curve The curve.
+   * @param ypx The $y + x$ value.
+   * @param ymx The $y - x$ value.
+   * @param xy2d The $2 * d * x * y$ value.
+   * @return The group element in PRECOMP representation.
+   */
+  public static GroupElement precomp(
+      final Curve curve, final FieldElement ypx, final FieldElement ymx, final FieldElement xy2d) {
+    return new GroupElement(curve, Representation.PRECOMP, ypx, ymx, xy2d, null);
+  }
+
+  /**
+   * Creates a new group element in CACHED representation.
+   *
+   * @param curve The curve.
+   * @param YpX The $Y + X$ value.
+   * @param YmX The $Y - X$ value.
+   * @param Z The $Z$ coordinate.
+   * @param T2d The $2 * d * T$ value.
+   * @return The group element in CACHED representation.
+   */
+  public static GroupElement cached(
+      final Curve curve,
+      final FieldElement YpX,
+      final FieldElement YmX,
+      final FieldElement Z,
+      final FieldElement T2d) {
+    return new GroupElement(curve, Representation.CACHED, YpX, YmX, Z, T2d);
+  }
+
+  /** Variable is package private only so that tests run. */
+  final Curve curve;
+
+  /** Variable is package private only so that tests run. */
+  final Representation repr;
+
+  /** Variable is package private only so that tests run. */
+  final FieldElement X;
+
+  /** Variable is package private only so that tests run. */
+  final FieldElement Y;
+
+  /** Variable is package private only so that tests run. */
+  final FieldElement Z;
+
+  /** Variable is package private only so that tests run. */
+  final FieldElement T;
+
+  /**
+   * Precomputed table for {@link #scalarMultiply(byte[])}, filled if necessary.
+   *
+   * <p>Variable is package private only so that tests run.
+   */
+  final GroupElement[][] precmp;
+
+  /**
+   * Precomputed table for , filled if necessary.
+   *
+   * <p>Variable is package private only so that tests run.
+   */
+  final GroupElement[] dblPrecmp;
+
+  /**
+   * Creates a group element for a curve, without any pre-computation.
+   *
+   * @param curve The curve.
+   * @param repr The representation used to represent the group element.
+   * @param X The $X$ coordinate.
+   * @param Y The $Y$ coordinate.
+   * @param Z The $Z$ coordinate.
+   * @param T The $T$ coordinate.
+   */
+  public GroupElement(
+      final Curve curve,
+      final Representation repr,
+      final FieldElement X,
+      final FieldElement Y,
+      final FieldElement Z,
+      final FieldElement T) {
+    this(curve, repr, X, Y, Z, T, false);
+  }
+
+  /**
+   * Creates a group element for a curve, with optional pre-computation.
+   *
+   * @param curve The curve.
+   * @param repr The representation used to represent the group element.
+   * @param X The $X$ coordinate.
+   * @param Y The $Y$ coordinate.
+   * @param Z The $Z$ coordinate.
+   * @param T The $T$ coordinate.
+   * @param precomputeDouble If true, populate dblPrecmp, else set to null.
+   */
+  public GroupElement(
+      final Curve curve,
+      final Representation repr,
+      final FieldElement X,
+      final FieldElement Y,
+      final FieldElement Z,
+      final FieldElement T,
+      final boolean precomputeDouble) {
+    this.curve = curve;
+    this.repr = repr;
+    this.X = X;
+    this.Y = Y;
+    this.Z = Z;
+    this.T = T;
+    this.precmp = null;
+    this.dblPrecmp = precomputeDouble ? precomputeDouble() : null;
+  }
+
+  /**
+   * Creates a group element for a curve from a given encoded point. No pre-computation.
+   *
+   * <p>A point $(x,y)$ is encoded by storing $y$ in bit 0 to bit 254 and the sign of $x$ in bit
+   * 255. $x$ is recovered in the following way:
+   *
+   * <ul>
+   *   <li>$x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v}$ with $u = y^2 -
+   *       1$ and $v = d * y^2 + 1$.
+   *   <li>Setting $β = (u * v^3) * (u * v^7)^{((q - 5) / 8)}$ one has $β^2 = \pm(u / v)$.
+   *   <li>If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
+   *   <li>Set $x := β$.
+   *   <li>If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
+   * </ul>
+   *
+   * @param curve The curve.
+   * @param s The encoded point.
+   */
+  public GroupElement(final Curve curve, final byte[] s) {
+    this(curve, s, false);
+  }
+
+  /**
+   * Creates a group element for a curve from a given encoded point. With optional pre-computation.
+   *
+   * <p>A point $(x,y)$ is encoded by storing $y$ in bit 0 to bit 254 and the sign of $x$ in bit
+   * 255. $x$ is recovered in the following way:
+   *
+   * <ul>
+   *   <li>$x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v}$ with $u = y^2 -
+   *       1$ and $v = d * y^2 + 1$.
+   *   <li>Setting $β = (u * v^3) * (u * v^7)^{((q - 5) / 8)}$ one has $β^2 = \pm(u / v)$.
+   *   <li>If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$.
+   *   <li>Set $x := β$.
+   *   <li>If $sign(x) \ne$ bit 255 of $s$ then negate $x$.
+   * </ul>
+   *
+   * @param curve The curve.
+   * @param s The encoded point.
+   * @param precomputeSingleAndDouble If true, populate both precmp and dblPrecmp, else set both to
+   *     null.
+   */
+  public GroupElement(final Curve curve, final byte[] s, boolean precomputeSingleAndDouble) {
+    FieldElement x, y, yy, u, v, v3, vxx, check;
+    y = curve.getField().fromByteArray(s);
+    yy = y.square();
+
+    // u = y^2-1
+    u = yy.subtractOne();
+
+    // v = dy^2+1
+    v = yy.multiply(curve.getD()).addOne();
+
+    // v3 = v^3
+    v3 = v.square().multiply(v);
+
+    // x = (v3^2)vu, aka x = uv^7
+    x = v3.square().multiply(v).multiply(u);
+
+    //  x = (uv^7)^((q-5)/8)
+    x = x.pow22523();
+
+    // x = uv^3(uv^7)^((q-5)/8)
+    x = v3.multiply(u).multiply(x);
+
+    vxx = x.square().multiply(v);
+    check = vxx.subtract(u); // vx^2-u
+    if (check.isNonZero()) {
+      check = vxx.add(u); // vx^2+u
+
+      if (check.isNonZero()) throw new IllegalArgumentException("not a valid GroupElement");
+      x = x.multiply(curve.getI());
+    }
+
+    if ((x.isNegative() ? 1 : 0) != Utils.bit(s, curve.getField().getb() - 1)) {
+      x = x.negate();
+    }
+
+    this.curve = curve;
+    this.repr = Representation.P3;
+    this.X = x;
+    this.Y = y;
+    this.Z = curve.getField().ONE;
+    this.T = this.X.multiply(this.Y);
+    if (precomputeSingleAndDouble) {
+      precmp = precomputeSingle();
+      dblPrecmp = precomputeDouble();
+    } else {
+      precmp = null;
+      dblPrecmp = null;
+    }
+  }
+
+  /**
+   * Gets the representation of the group element.
+   *
+   * @return The representation.
+   */
+  public Representation getRepresentation() {
+    return this.repr;
+  }
+
+  /**
+   * Converts the group element to an encoded point on the curve.
+   *
+   * @return The encoded point as byte array.
+   */
+  public byte[] toByteArray() {
+    switch (this.repr) {
+      case P2:
+      case P3:
+        FieldElement recip = Z.invert();
+        FieldElement x = X.multiply(recip);
+        FieldElement y = Y.multiply(recip);
+        byte[] s = y.toByteArray();
+        s[s.length - 1] |= (x.isNegative() ? (byte) 0x80 : 0);
+        return s;
+      default:
+        return toP2().toByteArray();
+    }
+  }
+
+  /**
+   * Converts the group element to the P2 representation.
+   *
+   * @return The group element in the P2 representation.
+   */
+  public GroupElement toP2() {
+    return toRep(Representation.P2);
+  }
+
+  /**
+   * Converts the group element to the P3 representation.
+   *
+   * @return The group element in the P3 representation.
+   */
+  public GroupElement toP3() {
+    return toRep(Representation.P3);
+  }
+
+  /**
+   * Converts the group element to the P3 representation, with dblPrecmp populated.
+   *
+   * @return The group element in the P3 representation.
+   */
+  public GroupElement toP3PrecomputeDouble() {
+    return toRep(Representation.P3PrecomputedDouble);
+  }
+
+  /**
+   * Converts the group element to the CACHED representation.
+   *
+   * @return The group element in the CACHED representation.
+   */
+  public GroupElement toCached() {
+    return toRep(Representation.CACHED);
+  }
+
+  /**
+   * Convert a GroupElement from one Representation to another. TODO-CR: Add additional conversion?
+   * $r = p$
+   *
+   * <p>Supported conversions:
+   *
+   * <p>
+   *
+   * <ul>
+   *   <li>P3 $\rightarrow$ P2
+   *   <li>P3 $\rightarrow$ CACHED (1 multiply, 1 add, 1 subtract)
+   *   <li>P1P1 $\rightarrow$ P2 (3 multiply)
+   *   <li>P1P1 $\rightarrow$ P3 (4 multiply)
+   *
+   * @param repr The representation to convert to.
+   * @return A new group element in the given representation.
+   */
+  private GroupElement toRep(final Representation repr) {
+    switch (this.repr) {
+      case P2:
+        if (repr == Representation.P2) {
+          return p2(this.curve, this.X, this.Y, this.Z);
+        }
+        throw new IllegalArgumentException();
+      case P3:
+        switch (repr) {
+          case P2:
+            return p2(this.curve, this.X, this.Y, this.Z);
+          case P3:
+            return p3(this.curve, this.X, this.Y, this.Z, this.T);
+          case CACHED:
+            return cached(
+                this.curve,
+                this.Y.add(this.X),
+                this.Y.subtract(this.X),
+                this.Z,
+                this.T.multiply(this.curve.get2D()));
+          default:
+            throw new IllegalArgumentException();
+        }
+      case P1P1:
+        switch (repr) {
+          case P2:
+            return p2(
+                this.curve, this.X.multiply(this.T), Y.multiply(this.Z), this.Z.multiply(this.T));
+          case P3:
+            return p3(
+                this.curve,
+                this.X.multiply(this.T),
+                Y.multiply(this.Z),
+                this.Z.multiply(this.T),
+                this.X.multiply(this.Y),
+                false);
+          case P3PrecomputedDouble:
+            return p3(
+                this.curve,
+                this.X.multiply(this.T),
+                Y.multiply(this.Z),
+                this.Z.multiply(this.T),
+                this.X.multiply(this.Y),
+                true);
+          case P1P1:
+            return p1p1(this.curve, this.X, this.Y, this.Z, this.T);
+          default:
+            throw new IllegalArgumentException();
+        }
+      case PRECOMP:
+        if (repr == Representation.PRECOMP) {
+          return precomp(this.curve, this.X, this.Y, this.Z);
+        }
+        throw new IllegalArgumentException();
+      case CACHED:
+        if (repr == Representation.CACHED) {
+          return cached(this.curve, this.X, this.Y, this.Z, this.T);
+        }
+        throw new IllegalArgumentException();
+      default:
+        throw new UnsupportedOperationException();
+    }
+  }
+
+  /** Precomputes table for {@link #scalarMultiply(byte[])}. */
+  private GroupElement[][] precomputeSingle() {
+    // Precomputation for single scalar multiplication.
+    GroupElement[][] precmp = new GroupElement[32][8];
+    // TODO-CR BR: check that this == base point when the method is called.
+    GroupElement Bi = this;
+    for (int i = 0; i < 32; i++) {
+      GroupElement Bij = Bi;
+      for (int j = 0; j < 8; j++) {
+        final FieldElement recip = Bij.Z.invert();
+        final FieldElement x = Bij.X.multiply(recip);
+        final FieldElement y = Bij.Y.multiply(recip);
+        precmp[i][j] =
+            precomp(
+                this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D()));
+        Bij = Bij.add(Bi.toCached()).toP3();
+      }
+      // Only every second summand is precomputed (16^2 = 256)
+      for (int k = 0; k < 8; k++) {
+        Bi = Bi.add(Bi.toCached()).toP3();
+      }
+    }
+    return precmp;
+  }
+
+  /** Precomputes table for . */
+  private GroupElement[] precomputeDouble() {
+    // Precomputation for double scalar multiplication.
+    // P,3P,5P,7P,9P,11P,13P,15P
+    GroupElement[] dblPrecmp = new GroupElement[8];
+    GroupElement Bi = this;
+    for (int i = 0; i < 8; i++) {
+      final FieldElement recip = Bi.Z.invert();
+      final FieldElement x = Bi.X.multiply(recip);
+      final FieldElement y = Bi.Y.multiply(recip);
+      dblPrecmp[i] =
+          precomp(this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D()));
+      // Bi = edwards(B,edwards(B,Bi))
+      Bi = this.add(this.add(Bi.toCached()).toP3().toCached()).toP3();
+    }
+    return dblPrecmp;
+  }
+
+  /**
+   * Doubles a given group element $p$ in $P^2$ or $P^3$ representation and returns the result in $P
+   * \times P$ representation. $r = 2 * p$ where $p = (X : Y : Z)$ or $p = (X : Y : Z : T)$
+   *
+   * <p>$r$ in $P \times P$ representation:
+   *
+   * <p>$r = ((X' : Z'), (Y' : T'))$ where
+   *
+   * <ul>
+   *   <li>$X' = (X + Y)^2 - (Y^2 + X^2)$
+   *   <li>$Y' = Y^2 + X^2$
+   *   <li>$Z' = y^2 - X^2$
+   *   <li>$T' = 2 * Z^2 - (y^2 - X^2)$
+   * </ul>
+   *
+   * <p>$r$ converted from $P \times P$ to $P^2$ representation:
+   *
+   * <p>$r = (X'' : Y'' : Z'')$ where
+   *
+   * <ul>
+   *   <li>$X'' = X' * Z' = ((X + Y)^2 - Y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$
+   *   <li>$Y'' = Y' * T' = (Y^2 + X^2) * (2 * Z^2 - (y^2 - X^2))$
+   *   <li>$Z'' = Z' * T' = (y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$
+   * </ul>
+   *
+   * <p>Formula for the $P^2$ representation is in agreement with the formula given in [4] page 12
+   * (with $a = -1$) up to a common factor -1 which does not matter:
+   *
+   * <p>$$ B = (X + Y)^2; C = X^2; D = Y^2; E = -C = -X^2; F := E + D = Y^2 - X^2; H = Z^2; J = F −
+   * 2 * H; \\ X3 = (B − C − D) · J = X' * (-T'); \\ Y3 = F · (E − D) = Z' * (-Y'); \\ Z3 = F · J =
+   * Z' * (-T'). $$
+   *
+   * @return The P1P1 representation
+   */
+  public GroupElement dbl() {
+    switch (this.repr) {
+      case P2:
+      case P3: // Ignore T for P3 representation
+        FieldElement XX, YY, B, A, AA, Yn, Zn;
+        XX = this.X.square();
+        YY = this.Y.square();
+        B = this.Z.squareAndDouble();
+        A = this.X.add(this.Y);
+        AA = A.square();
+        Yn = YY.add(XX);
+        Zn = YY.subtract(XX);
+        return p1p1(this.curve, AA.subtract(Yn), Yn, Zn, B.subtract(Zn));
+      default:
+        throw new UnsupportedOperationException();
+    }
+  }
+
+  /**
+   * GroupElement addition using the twisted Edwards addition law with extended coordinates
+   * (Hisil2008).
+   *
+   * <p>this must be in $P^3$ representation and $q$ in PRECOMP representation. $r = p + q$ where $p
+   * = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d *
+   * X2/Z2 * Y2/Z2)$
+   *
+   * <p>$r$ in $P \times P$ representation:
+   *
+   * <p>$r = ((X' : Z'), (Y' : T'))$ where
+   *
+   * <p>
+   *
+   * <ul>
+   *   <li>$X' = (Y1 + X1) * q.X - (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2))
+   *       * 1/Z2$
+   *   <li>$Y' = (Y1 + X1) * q.X + (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2))
+   *       * 1/Z2$
+   *   <li>$Z' = 2 * Z1 + T1 * q.Z = 2 * Z1 + T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 + 2 * d *
+   *       T1 * T2) * 1/Z2$
+   *   <li>$T' = 2 * Z1 - T1 * q.Z = 2 * Z1 - T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 - 2 * d *
+   *       T1 * T2) * 1/Z2$
+   * </ul>
+   *
+   * <p>Setting $A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 *
+   * Z1 * Z2$ we get
+   *
+   * <p>
+   *
+   * <ul>
+   *   <li>$X' = (B - A) * 1/Z2$
+   *   <li>$Y' = (B + A) * 1/Z2$
+   *   <li>$Z' = (D + C) * 1/Z2$
+   *   <li>$T' = (D - C) * 1/Z2$
+   * </ul>
+   *
+   * <p>$r$ converted from $P \times P$ to $P^2$ representation:
+   *
+   * <p>$r = (X'' : Y'' : Z'' : T'')$ where
+   *
+   * <p>
+   *
+   * <ul>
+   *   <li>$X'' = X' * Z' = (B - A) * (D + C) * 1/Z2^2$
+   *   <li>$Y'' = Y' * T' = (B + A) * (D - C) * 1/Z2^2$
+   *   <li>$Z'' = Z' * T' = (D + C) * (D - C) * 1/Z2^2$
+   *   <li>$T'' = X' * Y' = (B - A) * (B + A) * 1/Z2^2$
+   * </ul>
+   *
+   * <p>TODO-CR BR: Formula for the $P^2$ representation is not in agreement with the formula given
+   * in [2] page 6<br>
+   * TODO-CR BR: (the common factor $1/Z2^2$ does not matter):<br>
+   * $$ E = B - A, F = D - C, G = D + C, H = B + A \\ X3 = E * F = (B - A) * (D - C); \\ Y3 = G * H
+   * = (D + C) * (B + A); \\ Z3 = F * G = (D - C) * (D + C); \\ T3 = E * H = (B - A) * (B + A); $$
+   *
+   * @param q the PRECOMP representation of the GroupElement to add.
+   * @return the P1P1 representation of the result.
+   */
+  private GroupElement madd(GroupElement q) {
+    if (this.repr != Representation.P3) throw new UnsupportedOperationException();
+    if (q.repr != Representation.PRECOMP) throw new IllegalArgumentException();
+
+    FieldElement YpX, YmX, A, B, C, D;
+    YpX = this.Y.add(this.X);
+    YmX = this.Y.subtract(this.X);
+    A = YpX.multiply(q.X); // q->y+x
+    B = YmX.multiply(q.Y); // q->y-x
+    C = q.Z.multiply(this.T); // q->2dxy
+    D = this.Z.add(this.Z);
+    return p1p1(this.curve, A.subtract(B), A.add(B), D.add(C), D.subtract(C));
+  }
+
+  /**
+   * GroupElement subtraction using the twisted Edwards addition law with extended coordinates
+   * (Hisil2008).
+   *
+   * <p>this must be in $P^3$ representation and $q$ in PRECOMP representation. $r = p - q$ where $p
+   * = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d *
+   * X2/Z2 * Y2/Z2)$
+   *
+   * <p>Negating $q$ means negating the value of $X2$ and $T2$ (the latter is irrelevant here). The
+   * formula is in accordance to {@link #madd the above addition}.
+   *
+   * @param q the PRECOMP representation of the GroupElement to subtract.
+   * @return the P1P1 representation of the result.
+   */
+  private GroupElement msub(GroupElement q) {
+    if (this.repr != Representation.P3) throw new UnsupportedOperationException();
+    if (q.repr != Representation.PRECOMP) throw new IllegalArgumentException();
+
+    FieldElement YpX, YmX, A, B, C, D;
+    YpX = this.Y.add(this.X);
+    YmX = this.Y.subtract(this.X);
+    A = YpX.multiply(q.Y); // q->y-x
+    B = YmX.multiply(q.X); // q->y+x
+    C = q.Z.multiply(this.T); // q->2dxy
+    D = this.Z.add(this.Z);
+    return p1p1(this.curve, A.subtract(B), A.add(B), D.subtract(C), D.add(C));
+  }
+
+  /**
+   * GroupElement addition using the twisted Edwards addition law with extended coordinates
+   * (Hisil2008).
+   *
+   * <p>this must be in $P^3$ representation and $q$ in CACHED representation. $r = p + q$ where $p
+   * = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z, q.T) = (Y2 + X2, Y2 - X2, Z2, 2 * d * T2)$
+   *
+   * <p>$r$ in $P \times P$ representation:
+   *
+   * <ul>
+   *   <li>$X' = (Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)$
+   *   <li>$Y' = (Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)$
+   *   <li>$Z' = 2 * Z1 * Z2 + 2 * d * T1 * T2$
+   *   <li>$T' = 2 * Z1 * T2 - 2 * d * T1 * T2$
+   * </ul>
+   *
+   * <p>Setting $A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 *
+   * Z1 * Z2$ we get
+   *
+   * <ul>
+   *   <li>$X' = (B - A)$
+   *   <li>$Y' = (B + A)$
+   *   <li>$Z' = (D + C)$
+   *   <li>$T' = (D - C)$
+   * </ul>
+   *
+   * <p>Same result as in {@link #madd} (up to a common factor which does not matter).
+   *
+   * @param q the CACHED representation of the GroupElement to add.
+   * @return the P1P1 representation of the result.
+   */
+  public GroupElement add(GroupElement q) {
+    if (this.repr != Representation.P3) throw new UnsupportedOperationException();
+    if (q.repr != Representation.CACHED) throw new IllegalArgumentException();
+
+    FieldElement YpX, YmX, A, B, C, ZZ, D;
+    YpX = this.Y.add(this.X);
+    YmX = this.Y.subtract(this.X);
+    A = YpX.multiply(q.X); // q->Y+X
+    B = YmX.multiply(q.Y); // q->Y-X
+    C = q.T.multiply(this.T); // q->2dT
+    ZZ = this.Z.multiply(q.Z);
+    D = ZZ.add(ZZ);
+    return p1p1(this.curve, A.subtract(B), A.add(B), D.add(C), D.subtract(C));
+  }
+
+  /**
+   * GroupElement subtraction using the twisted Edwards addition law with extended coordinates
+   * (Hisil2008).
+   *
+   * <p>$r = p - q$
+   *
+   * <p>Negating $q$ means negating the value of the coordinate $X2$ and $T2$. The formula is in
+   * accordance to {@link #add the above addition}.
+   *
+   * @param q the PRECOMP representation of the GroupElement to subtract.
+   * @return the P1P1 representation of the result.
+   */
+  public GroupElement sub(GroupElement q) {
+    if (this.repr != Representation.P3) throw new UnsupportedOperationException();
+    if (q.repr != Representation.CACHED) throw new IllegalArgumentException();
+
+    FieldElement YpX, YmX, A, B, C, ZZ, D;
+    YpX = Y.add(X);
+    YmX = Y.subtract(X);
+    A = YpX.multiply(q.Y); // q->Y-X
+    B = YmX.multiply(q.X); // q->Y+X
+    C = q.T.multiply(T); // q->2dT
+    ZZ = Z.multiply(q.Z);
+    D = ZZ.add(ZZ);
+    return p1p1(curve, A.subtract(B), A.add(B), D.subtract(C), D.add(C));
+  }
+
+  /**
+   * Negates this group element by subtracting it from the neutral group element.
+   *
+   * <p>TODO-CR BR: why not simply negate the coordinates $X$ and $T$?
+   *
+   * @return The negative of this group element.
+   */
+  public GroupElement negate() {
+    if (this.repr != Representation.P3) throw new UnsupportedOperationException();
+    return this.curve.getZero(Representation.P3).sub(toCached()).toP3PrecomputeDouble();
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(this.toByteArray());
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) return true;
+    if (!(obj instanceof GroupElement)) return false;
+    GroupElement ge = (GroupElement) obj;
+    if (!this.repr.equals(ge.repr)) {
+      try {
+        ge = ge.toRep(this.repr);
+      } catch (RuntimeException e) {
+        return false;
+      }
+    }
+    switch (this.repr) {
+      case P2:
+      case P3:
+        // Try easy way first
+        if (this.Z.equals(ge.Z)) return this.X.equals(ge.X) && this.Y.equals(ge.Y);
+        // X1/Z1 = X2/Z2 --> X1*Z2 = X2*Z1
+        final FieldElement x1 = this.X.multiply(ge.Z);
+        final FieldElement y1 = this.Y.multiply(ge.Z);
+        final FieldElement x2 = ge.X.multiply(this.Z);
+        final FieldElement y2 = ge.Y.multiply(this.Z);
+        return x1.equals(x2) && y1.equals(y2);
+      case P1P1:
+        return toP2().equals(ge);
+      case PRECOMP:
+        // Compare directly, PRECOMP is derived directly from x and y
+        return this.X.equals(ge.X) && this.Y.equals(ge.Y) && this.Z.equals(ge.Z);
+      case CACHED:
+        // Try easy way first
+        if (this.Z.equals(ge.Z))
+          return this.X.equals(ge.X) && this.Y.equals(ge.Y) && this.T.equals(ge.T);
+        // (Y+X)/Z = y+x etc.
+        final FieldElement x3 = this.X.multiply(ge.Z);
+        final FieldElement y3 = this.Y.multiply(ge.Z);
+        final FieldElement t3 = this.T.multiply(ge.Z);
+        final FieldElement x4 = ge.X.multiply(this.Z);
+        final FieldElement y4 = ge.Y.multiply(this.Z);
+        final FieldElement t4 = ge.T.multiply(this.Z);
+        return x3.equals(x4) && y3.equals(y4) && t3.equals(t4);
+      default:
+        return false;
+    }
+  }
+
+  /**
+   * Convert a to radix 16.
+   *
+   * <p>Method is package private only so that tests run.
+   *
+   * @param a $= a[0]+256*a[1]+...+256^{31} a[31]$
+   * @return 64 bytes, each between -8 and 7
+   */
+  static byte[] toRadix16(final byte[] a) {
+    final byte[] e = new byte[64];
+    int i;
+    // Radix 16 notation
+    for (i = 0; i < 32; i++) {
+      e[2 * i] = (byte) (a[i] & 15);
+      e[2 * i + 1] = (byte) ((a[i] >> 4) & 15);
+    }
+    /* each e[i] is between 0 and 15 */
+    /* e[63] is between 0 and 7 */
+    int carry = 0;
+    for (i = 0; i < 63; i++) {
+      e[i] += carry;
+      carry = e[i] + 8;
+      carry >>= 4;
+      e[i] -= carry << 4;
+    }
+    e[63] += carry;
+    /* each e[i] is between -8 and 7 */
+    return e;
+  }
+
+  /**
+   * Constant-time conditional move.
+   *
+   * <p>Replaces this with $u$ if $b == 1$.<br>
+   * Replaces this with this if $b == 0$.
+   *
+   * <p>Method is package private only so that tests run.
+   *
+   * @param u The group element to return if $b == 1$.
+   * @param b in $\{0, 1\}$
+   * @return $u$ if $b == 1$; this if $b == 0$. Results undefined if $b$ is not in $\{0, 1\}$.
+   */
+  GroupElement cmov(final GroupElement u, final int b) {
+    return precomp(curve, X.cmov(u.X, b), Y.cmov(u.Y, b), Z.cmov(u.Z, b));
+  }
+
+  /**
+   * Look up $16^i r_i B$ in the precomputed table.
+   *
+   * <p>No secret array indices, no secret branching. Constant time.
+   *
+   * <p>Must have previously precomputed.
+   *
+   * <p>Method is package private only so that tests run.
+   *
+   * @param pos $= i/2$ for $i$ in $\{0, 2, 4,..., 62\}$
+   * @param b $= r_i$
+   * @return the GroupElement
+   */
+  GroupElement select(final int pos, final int b) {
+    // Is r_i negative?
+    final int bnegative = Utils.negative(b);
+    // |r_i|
+    final int babs = b - (((-bnegative) & b) << 1);
+
+    // 16^i |r_i| B
+    final GroupElement t =
+        this.curve
+            .getZero(Representation.PRECOMP)
+            .cmov(this.precmp[pos][0], Utils.equal(babs, 1))
+            .cmov(this.precmp[pos][1], Utils.equal(babs, 2))
+            .cmov(this.precmp[pos][2], Utils.equal(babs, 3))
+            .cmov(this.precmp[pos][3], Utils.equal(babs, 4))
+            .cmov(this.precmp[pos][4], Utils.equal(babs, 5))
+            .cmov(this.precmp[pos][5], Utils.equal(babs, 6))
+            .cmov(this.precmp[pos][6], Utils.equal(babs, 7))
+            .cmov(this.precmp[pos][7], Utils.equal(babs, 8));
+    // -16^i |r_i| B
+    final GroupElement tminus = precomp(curve, t.Y, t.X, t.Z.negate());
+    // 16^i r_i B
+    return t.cmov(tminus, bnegative);
+  }
+
+  /**
+   * $h = a * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$ and $B$ is this point. If its lookup
+   * table has not been precomputed, it will be at the start of the method (and cached for later
+   * calls). Constant time.
+   *
+   * <p>Preconditions: (TODO: Check this applies here) $a[31] \le 127$
+   *
+   * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$
+   * @return the GroupElement
+   */
+  public GroupElement scalarMultiply(final byte[] a) {
+    GroupElement t;
+    int i;
+
+    final byte[] e = toRadix16(a);
+
+    GroupElement h = this.curve.getZero(Representation.P3);
+    for (i = 1; i < 64; i += 2) {
+      t = select(i / 2, e[i]);
+      h = h.madd(t).toP3();
+    }
+
+    h = h.dbl().toP2().dbl().toP2().dbl().toP2().dbl().toP3();
+
+    for (i = 0; i < 64; i += 2) {
+      t = select(i / 2, e[i]);
+      h = h.madd(t).toP3();
+    }
+
+    return h;
+  }
+
+  /**
+   * Calculates a sliding-windows base 2 representation for a given value $a$. To learn more about
+   * it see [6] page 8.
+   *
+   * <p>Output: $r$ which satisfies $a = r0 * 2^0 + r1 * 2^1 + \dots + r255 * 2^{255}$ with $ri$ in
+   * $\{-15, -13, -11, -9, -7, -5, -3, -1, 0, 1, 3, 5, 7, 9, 11, 13, 15\}$
+   *
+   * <p>Method is package private only so that tests run.
+   *
+   * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$.
+   * @return The byte array $r$ in the above described form.
+   */
+  static byte[] slide(final byte[] a) {
+    byte[] r = new byte[256];
+
+    // Put each bit of 'a' into a separate byte, 0 or 1
+    for (int i = 0; i < 256; ++i) {
+      r[i] = (byte) (1 & (a[i >> 3] >> (i & 7)));
+    }
+
+    // Note: r[i] will always be odd.
+    for (int i = 0; i < 256; ++i) {
+      if (r[i] != 0) {
+        for (int b = 1; b <= 6 && i + b < 256; ++b) {
+          // Accumulate bits if possible
+          if (r[i + b] != 0) {
+            if (r[i] + (r[i + b] << b) <= 15) {
+              r[i] += r[i + b] << b;
+              r[i + b] = 0;
+            } else if (r[i] - (r[i + b] << b) >= -15) {
+              r[i] -= r[i + b] << b;
+              for (int k = i + b; k < 256; ++k) {
+                if (r[k] == 0) {
+                  r[k] = 1;
+                  break;
+                }
+                r[k] = 0;
+              }
+            } else break;
+          }
+        }
+      }
+    }
+
+    return r;
+  }
+
+  /**
+   * Verify that a point is on the curve.
+   *
+   * @param curve The curve to check.
+   * @return true if the point lies on the curve.
+   */
+  public boolean isOnCurve(Curve curve) {
+    switch (repr) {
+      case P2:
+      case P3:
+        FieldElement recip = Z.invert();
+        FieldElement x = X.multiply(recip);
+        FieldElement y = Y.multiply(recip);
+        FieldElement xx = x.square();
+        FieldElement yy = y.square();
+        FieldElement dxxyy = curve.getD().multiply(xx).multiply(yy);
+        return curve.getField().ONE.add(dxxyy).add(xx).equals(yy);
+
+      default:
+        return toP2().isOnCurve(curve);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return "[GroupElement\nX=" + X + "\nY=" + Y + "\nZ=" + Z + "\nT=" + T + "\n]";
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ScalarOps.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ScalarOps.java
new file mode 100644
index 0000000..c52b7f2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ScalarOps.java
@@ -0,0 +1,25 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math;
+
+public interface ScalarOps {
+  /**
+   * Reduce the given scalar mod $l$.
+   *
+   * <p>From the Ed25519 paper:<br>
+   * Here we interpret $2b$-bit strings in little-endian form as integers in $\{0, 1,...,
+   * 2^{(2b)}-1\}$.
+   *
+   * @param s the scalar to reduce
+   * @return $s \bmod l$
+   */
+  byte[] reduce(byte[] s);
+
+  /**
+   * $r = (a * b + c) \bmod l$
+   *
+   * @param a a scalar
+   * @param b a scalar
+   * @param c a scalar
+   * @return $(a*b + c) \bmod l$
+   */
+  byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c);
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519FieldElement.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519FieldElement.java
new file mode 100644
index 0000000..37fb78b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519FieldElement.java
@@ -0,0 +1,1050 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ed25519;
+
+import java.util.Arrays;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.Utils;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.Field;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.FieldElement;
+
+/**
+ * Class to represent a field element of the finite field $p = 2^{255} - 19$ elements.
+ *
+ * <p>An element $t$, entries $t[0] \dots t[9]$, represents the integer $t[0]+2^{26} t[1]+2^{51}
+ * t[2]+2^{77} t[3]+2^{102} t[4]+\dots+2^{230} t[9]$. Bounds on each $t[i]$ vary depending on
+ * context.
+ *
+ * <p>Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
+ */
+public class Ed25519FieldElement extends FieldElement {
+  private static final long serialVersionUID = -2455098303824960263L;
+  /** Variable is package private for encoding. */
+  final int[] t;
+
+  /**
+   * Creates a field element.
+   *
+   * @param f The underlying field, must be the finite field with $p = 2^{255} - 19$ elements
+   * @param t The $2^{25.5}$ bit representation of the field element.
+   */
+  public Ed25519FieldElement(Field f, int[] t) {
+    super(f);
+    if (t.length != 10) throw new IllegalArgumentException("Invalid radix-2^51 representation");
+    this.t = t;
+  }
+
+  private static final byte[] ZERO = new byte[32];
+
+  /**
+   * Gets a value indicating whether or not the field element is non-zero.
+   *
+   * @return 1 if it is non-zero, 0 otherwise.
+   */
+  public boolean isNonZero() {
+    final byte[] s = toByteArray();
+    return Utils.equal(s, ZERO) == 0;
+  }
+
+  /**
+   * $h = f + g$
+   *
+   * <p>TODO-CR BR: $h$ is allocated via new, probably not a good idea. Do we need the copying into
+   * temp variables if we do that?
+   *
+   * <p>Preconditions:
+   *
+   * <ul>
+   *   <li>$|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
+   *   <li>$|g|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
+   * </ul>
+   *
+   * <p>Postconditions:
+   *
+   * <ul>
+   *   <li>$|h|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25},$ etc.
+   * </ul>
+   *
+   * @param val The field element to add.
+   * @return The field element this + val.
+   */
+  public FieldElement add(FieldElement val) {
+    int[] g = ((Ed25519FieldElement) val).t;
+    int[] h = new int[10];
+    for (int i = 0; i < 10; i++) {
+      h[i] = t[i] + g[i];
+    }
+    return new Ed25519FieldElement(f, h);
+  }
+
+  /**
+   * $h = f - g$
+   *
+   * <p>Can overlap $h$ with $f$ or $g$.
+   *
+   * <p>TODO-CR BR: See above.
+   *
+   * <p>Preconditions:
+   *
+   * <ul>
+   *   <li>$|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
+   *   <li>$|g|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
+   * </ul>
+   *
+   * <p>Postconditions:
+   *
+   * <ul>
+   *   <li>$|h|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25},$ etc.
+   * </ul>
+   *
+   * @param val The field element to subtract.
+   * @return The field element this - val.
+   */
+  public FieldElement subtract(FieldElement val) {
+    int[] g = ((Ed25519FieldElement) val).t;
+    int[] h = new int[10];
+    for (int i = 0; i < 10; i++) {
+      h[i] = t[i] - g[i];
+    }
+    return new Ed25519FieldElement(f, h);
+  }
+
+  /**
+   * $h = -f$
+   *
+   * <p>TODO-CR BR: see above.
+   *
+   * <p>Preconditions:
+   *
+   * <ul>
+   *   <li>$|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
+   * </ul>
+   *
+   * <p>Postconditions:
+   *
+   * <ul>
+   *   <li>$|h|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc.
+   * </ul>
+   *
+   * @return The field element (-1) * this.
+   */
+  public FieldElement negate() {
+    int[] h = new int[10];
+    for (int i = 0; i < 10; i++) {
+      h[i] = -t[i];
+    }
+    return new Ed25519FieldElement(f, h);
+  }
+
+  /**
+   * $h = f * g$
+   *
+   * <p>Can overlap $h$ with $f$ or $g$.
+   *
+   * <p>Preconditions:
+   *
+   * <ul>
+   *   <li>$|f|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
+   *   <li>$|g|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
+   * </ul>
+   *
+   * <p>Postconditions:
+   *
+   * <ul>
+   *   <li>$|h|$ bounded by $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc.
+   * </ul>
+   *
+   * <p>Notes on implementation strategy:
+   *
+   * <p>Using schoolbook multiplication. Karatsuba would save a little in some cost models.
+   *
+   * <p>Most multiplications by 2 and 19 are 32-bit precomputations; cheaper than 64-bit
+   * postcomputations.
+   *
+   * <p>There is one remaining multiplication by 19 in the carry chain; one *19 precomputation can
+   * be merged into this, but the resulting data flow is considerably less clean.
+   *
+   * <p>There are 12 carries below. 10 of them are 2-way parallelizable and vectorizable. Can get
+   * away with 11 carries, but then data flow is much deeper.
+   *
+   * <p>With tighter constraints on inputs can squeeze carries into int32.
+   *
+   * @param val The field element to multiply.
+   * @return The (reasonably reduced) field element this * val.
+   */
+  public FieldElement multiply(FieldElement val) {
+    int[] g = ((Ed25519FieldElement) val).t;
+    int g1_19 = 19 * g[1]; /* 1.959375*2^29 */
+    int g2_19 = 19 * g[2]; /* 1.959375*2^30; still ok */
+    int g3_19 = 19 * g[3];
+    int g4_19 = 19 * g[4];
+    int g5_19 = 19 * g[5];
+    int g6_19 = 19 * g[6];
+    int g7_19 = 19 * g[7];
+    int g8_19 = 19 * g[8];
+    int g9_19 = 19 * g[9];
+    int f1_2 = 2 * t[1];
+    int f3_2 = 2 * t[3];
+    int f5_2 = 2 * t[5];
+    int f7_2 = 2 * t[7];
+    int f9_2 = 2 * t[9];
+    long f0g0 = t[0] * (long) g[0];
+    long f0g1 = t[0] * (long) g[1];
+    long f0g2 = t[0] * (long) g[2];
+    long f0g3 = t[0] * (long) g[3];
+    long f0g4 = t[0] * (long) g[4];
+    long f0g5 = t[0] * (long) g[5];
+    long f0g6 = t[0] * (long) g[6];
+    long f0g7 = t[0] * (long) g[7];
+    long f0g8 = t[0] * (long) g[8];
+    long f0g9 = t[0] * (long) g[9];
+    long f1g0 = t[1] * (long) g[0];
+    long f1g1_2 = f1_2 * (long) g[1];
+    long f1g2 = t[1] * (long) g[2];
+    long f1g3_2 = f1_2 * (long) g[3];
+    long f1g4 = t[1] * (long) g[4];
+    long f1g5_2 = f1_2 * (long) g[5];
+    long f1g6 = t[1] * (long) g[6];
+    long f1g7_2 = f1_2 * (long) g[7];
+    long f1g8 = t[1] * (long) g[8];
+    long f1g9_38 = f1_2 * (long) g9_19;
+    long f2g0 = t[2] * (long) g[0];
+    long f2g1 = t[2] * (long) g[1];
+    long f2g2 = t[2] * (long) g[2];
+    long f2g3 = t[2] * (long) g[3];
+    long f2g4 = t[2] * (long) g[4];
+    long f2g5 = t[2] * (long) g[5];
+    long f2g6 = t[2] * (long) g[6];
+    long f2g7 = t[2] * (long) g[7];
+    long f2g8_19 = t[2] * (long) g8_19;
+    long f2g9_19 = t[2] * (long) g9_19;
+    long f3g0 = t[3] * (long) g[0];
+    long f3g1_2 = f3_2 * (long) g[1];
+    long f3g2 = t[3] * (long) g[2];
+    long f3g3_2 = f3_2 * (long) g[3];
+    long f3g4 = t[3] * (long) g[4];
+    long f3g5_2 = f3_2 * (long) g[5];
+    long f3g6 = t[3] * (long) g[6];
+    long f3g7_38 = f3_2 * (long) g7_19;
+    long f3g8_19 = t[3] * (long) g8_19;
+    long f3g9_38 = f3_2 * (long) g9_19;
+    long f4g0 = t[4] * (long) g[0];
+    long f4g1 = t[4] * (long) g[1];
+    long f4g2 = t[4] * (long) g[2];
+    long f4g3 = t[4] * (long) g[3];
+    long f4g4 = t[4] * (long) g[4];
+    long f4g5 = t[4] * (long) g[5];
+    long f4g6_19 = t[4] * (long) g6_19;
+    long f4g7_19 = t[4] * (long) g7_19;
+    long f4g8_19 = t[4] * (long) g8_19;
+    long f4g9_19 = t[4] * (long) g9_19;
+    long f5g0 = t[5] * (long) g[0];
+    long f5g1_2 = f5_2 * (long) g[1];
+    long f5g2 = t[5] * (long) g[2];
+    long f5g3_2 = f5_2 * (long) g[3];
+    long f5g4 = t[5] * (long) g[4];
+    long f5g5_38 = f5_2 * (long) g5_19;
+    long f5g6_19 = t[5] * (long) g6_19;
+    long f5g7_38 = f5_2 * (long) g7_19;
+    long f5g8_19 = t[5] * (long) g8_19;
+    long f5g9_38 = f5_2 * (long) g9_19;
+    long f6g0 = t[6] * (long) g[0];
+    long f6g1 = t[6] * (long) g[1];
+    long f6g2 = t[6] * (long) g[2];
+    long f6g3 = t[6] * (long) g[3];
+    long f6g4_19 = t[6] * (long) g4_19;
+    long f6g5_19 = t[6] * (long) g5_19;
+    long f6g6_19 = t[6] * (long) g6_19;
+    long f6g7_19 = t[6] * (long) g7_19;
+    long f6g8_19 = t[6] * (long) g8_19;
+    long f6g9_19 = t[6] * (long) g9_19;
+    long f7g0 = t[7] * (long) g[0];
+    long f7g1_2 = f7_2 * (long) g[1];
+    long f7g2 = t[7] * (long) g[2];
+    long f7g3_38 = f7_2 * (long) g3_19;
+    long f7g4_19 = t[7] * (long) g4_19;
+    long f7g5_38 = f7_2 * (long) g5_19;
+    long f7g6_19 = t[7] * (long) g6_19;
+    long f7g7_38 = f7_2 * (long) g7_19;
+    long f7g8_19 = t[7] * (long) g8_19;
+    long f7g9_38 = f7_2 * (long) g9_19;
+    long f8g0 = t[8] * (long) g[0];
+    long f8g1 = t[8] * (long) g[1];
+    long f8g2_19 = t[8] * (long) g2_19;
+    long f8g3_19 = t[8] * (long) g3_19;
+    long f8g4_19 = t[8] * (long) g4_19;
+    long f8g5_19 = t[8] * (long) g5_19;
+    long f8g6_19 = t[8] * (long) g6_19;
+    long f8g7_19 = t[8] * (long) g7_19;
+    long f8g8_19 = t[8] * (long) g8_19;
+    long f8g9_19 = t[8] * (long) g9_19;
+    long f9g0 = t[9] * (long) g[0];
+    long f9g1_38 = f9_2 * (long) g1_19;
+    long f9g2_19 = t[9] * (long) g2_19;
+    long f9g3_38 = f9_2 * (long) g3_19;
+    long f9g4_19 = t[9] * (long) g4_19;
+    long f9g5_38 = f9_2 * (long) g5_19;
+    long f9g6_19 = t[9] * (long) g6_19;
+    long f9g7_38 = f9_2 * (long) g7_19;
+    long f9g8_19 = t[9] * (long) g8_19;
+    long f9g9_38 = f9_2 * (long) g9_19;
+
+    long h0 =
+        f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19
+            + f9g1_38;
+    long h1 =
+        f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
+    long h2 =
+        f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
+    long h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
+    long h4 =
+        f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
+    long h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
+    long h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
+    long h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
+    long h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
+    long h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0;
+    long carry0;
+    long carry1;
+    long carry2;
+    long carry3;
+    long carry4;
+    long carry5;
+    long carry6;
+    long carry7;
+    long carry8;
+    long carry9;
+
+    /*
+    |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
+      i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
+    |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
+      i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
+    */
+
+    carry0 = (h0 + (long) (1 << 25)) >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+    carry4 = (h4 + (long) (1 << 25)) >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+    /* |h0| <= 2^25 */
+    /* |h4| <= 2^25 */
+    /* |h1| <= 1.71*2^59 */
+    /* |h5| <= 1.71*2^59 */
+
+    carry1 = (h1 + (long) (1 << 24)) >> 25;
+    h2 += carry1;
+    h1 -= carry1 << 25;
+    carry5 = (h5 + (long) (1 << 24)) >> 25;
+    h6 += carry5;
+    h5 -= carry5 << 25;
+    /* |h1| <= 2^24; from now on fits into int32 */
+    /* |h5| <= 2^24; from now on fits into int32 */
+    /* |h2| <= 1.41*2^60 */
+    /* |h6| <= 1.41*2^60 */
+
+    carry2 = (h2 + (long) (1 << 25)) >> 26;
+    h3 += carry2;
+    h2 -= carry2 << 26;
+    carry6 = (h6 + (long) (1 << 25)) >> 26;
+    h7 += carry6;
+    h6 -= carry6 << 26;
+    /* |h2| <= 2^25; from now on fits into int32 unchanged */
+    /* |h6| <= 2^25; from now on fits into int32 unchanged */
+    /* |h3| <= 1.71*2^59 */
+    /* |h7| <= 1.71*2^59 */
+
+    carry3 = (h3 + (long) (1 << 24)) >> 25;
+    h4 += carry3;
+    h3 -= carry3 << 25;
+    carry7 = (h7 + (long) (1 << 24)) >> 25;
+    h8 += carry7;
+    h7 -= carry7 << 25;
+    /* |h3| <= 2^24; from now on fits into int32 unchanged */
+    /* |h7| <= 2^24; from now on fits into int32 unchanged */
+    /* |h4| <= 1.72*2^34 */
+    /* |h8| <= 1.41*2^60 */
+
+    carry4 = (h4 + (long) (1 << 25)) >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+    carry8 = (h8 + (long) (1 << 25)) >> 26;
+    h9 += carry8;
+    h8 -= carry8 << 26;
+    /* |h4| <= 2^25; from now on fits into int32 unchanged */
+    /* |h8| <= 2^25; from now on fits into int32 unchanged */
+    /* |h5| <= 1.01*2^24 */
+    /* |h9| <= 1.71*2^59 */
+
+    carry9 = (h9 + (long) (1 << 24)) >> 25;
+    h0 += carry9 * 19;
+    h9 -= carry9 << 25;
+    /* |h9| <= 2^24; from now on fits into int32 unchanged */
+    /* |h0| <= 1.1*2^39 */
+
+    carry0 = (h0 + (long) (1 << 25)) >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+    /* |h0| <= 2^25; from now on fits into int32 unchanged */
+    /* |h1| <= 1.01*2^24 */
+
+    int[] h = new int[10];
+    h[0] = (int) h0;
+    h[1] = (int) h1;
+    h[2] = (int) h2;
+    h[3] = (int) h3;
+    h[4] = (int) h4;
+    h[5] = (int) h5;
+    h[6] = (int) h6;
+    h[7] = (int) h7;
+    h[8] = (int) h8;
+    h[9] = (int) h9;
+    return new Ed25519FieldElement(f, h);
+  }
+
+  /**
+   * $h = f * f$
+   *
+   * <p>Can overlap $h$ with $f$.
+   *
+   * <p>Preconditions:
+   *
+   * <ul>
+   *   <li>$|f|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
+   * </ul>
+   *
+   * <p>Postconditions:
+   *
+   * <ul>
+   *   <li>$|h|$ bounded by $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc.
+   * </ul>
+   *
+   * <p>See {@link #multiply(FieldElement)} for discussion of implementation strategy.
+   *
+   * @return The (reasonably reduced) square of this field element.
+   */
+  public FieldElement square() {
+    int f0 = t[0];
+    int f1 = t[1];
+    int f2 = t[2];
+    int f3 = t[3];
+    int f4 = t[4];
+    int f5 = t[5];
+    int f6 = t[6];
+    int f7 = t[7];
+    int f8 = t[8];
+    int f9 = t[9];
+    int f0_2 = 2 * f0;
+    int f1_2 = 2 * f1;
+    int f2_2 = 2 * f2;
+    int f3_2 = 2 * f3;
+    int f4_2 = 2 * f4;
+    int f5_2 = 2 * f5;
+    int f6_2 = 2 * f6;
+    int f7_2 = 2 * f7;
+    int f5_38 = 38 * f5; /* 1.959375*2^30 */
+    int f6_19 = 19 * f6; /* 1.959375*2^30 */
+    int f7_38 = 38 * f7; /* 1.959375*2^30 */
+    int f8_19 = 19 * f8; /* 1.959375*2^30 */
+    int f9_38 = 38 * f9; /* 1.959375*2^30 */
+    long f0f0 = f0 * (long) f0;
+    long f0f1_2 = f0_2 * (long) f1;
+    long f0f2_2 = f0_2 * (long) f2;
+    long f0f3_2 = f0_2 * (long) f3;
+    long f0f4_2 = f0_2 * (long) f4;
+    long f0f5_2 = f0_2 * (long) f5;
+    long f0f6_2 = f0_2 * (long) f6;
+    long f0f7_2 = f0_2 * (long) f7;
+    long f0f8_2 = f0_2 * (long) f8;
+    long f0f9_2 = f0_2 * (long) f9;
+    long f1f1_2 = f1_2 * (long) f1;
+    long f1f2_2 = f1_2 * (long) f2;
+    long f1f3_4 = f1_2 * (long) f3_2;
+    long f1f4_2 = f1_2 * (long) f4;
+    long f1f5_4 = f1_2 * (long) f5_2;
+    long f1f6_2 = f1_2 * (long) f6;
+    long f1f7_4 = f1_2 * (long) f7_2;
+    long f1f8_2 = f1_2 * (long) f8;
+    long f1f9_76 = f1_2 * (long) f9_38;
+    long f2f2 = f2 * (long) f2;
+    long f2f3_2 = f2_2 * (long) f3;
+    long f2f4_2 = f2_2 * (long) f4;
+    long f2f5_2 = f2_2 * (long) f5;
+    long f2f6_2 = f2_2 * (long) f6;
+    long f2f7_2 = f2_2 * (long) f7;
+    long f2f8_38 = f2_2 * (long) f8_19;
+    long f2f9_38 = f2 * (long) f9_38;
+    long f3f3_2 = f3_2 * (long) f3;
+    long f3f4_2 = f3_2 * (long) f4;
+    long f3f5_4 = f3_2 * (long) f5_2;
+    long f3f6_2 = f3_2 * (long) f6;
+    long f3f7_76 = f3_2 * (long) f7_38;
+    long f3f8_38 = f3_2 * (long) f8_19;
+    long f3f9_76 = f3_2 * (long) f9_38;
+    long f4f4 = f4 * (long) f4;
+    long f4f5_2 = f4_2 * (long) f5;
+    long f4f6_38 = f4_2 * (long) f6_19;
+    long f4f7_38 = f4 * (long) f7_38;
+    long f4f8_38 = f4_2 * (long) f8_19;
+    long f4f9_38 = f4 * (long) f9_38;
+    long f5f5_38 = f5 * (long) f5_38;
+    long f5f6_38 = f5_2 * (long) f6_19;
+    long f5f7_76 = f5_2 * (long) f7_38;
+    long f5f8_38 = f5_2 * (long) f8_19;
+    long f5f9_76 = f5_2 * (long) f9_38;
+    long f6f6_19 = f6 * (long) f6_19;
+    long f6f7_38 = f6 * (long) f7_38;
+    long f6f8_38 = f6_2 * (long) f8_19;
+    long f6f9_38 = f6 * (long) f9_38;
+    long f7f7_38 = f7 * (long) f7_38;
+    long f7f8_38 = f7_2 * (long) f8_19;
+    long f7f9_76 = f7_2 * (long) f9_38;
+    long f8f8_19 = f8 * (long) f8_19;
+    long f8f9_38 = f8 * (long) f9_38;
+    long f9f9_38 = f9 * (long) f9_38;
+
+    long h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
+    long h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
+    long h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
+    long h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
+    long h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
+    long h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
+    long h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
+    long h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
+    long h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
+    long h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
+    long carry0;
+    long carry1;
+    long carry2;
+    long carry3;
+    long carry4;
+    long carry5;
+    long carry6;
+    long carry7;
+    long carry8;
+    long carry9;
+
+    carry0 = (h0 + (long) (1 << 25)) >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+    carry4 = (h4 + (long) (1 << 25)) >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+
+    carry1 = (h1 + (long) (1 << 24)) >> 25;
+    h2 += carry1;
+    h1 -= carry1 << 25;
+    carry5 = (h5 + (long) (1 << 24)) >> 25;
+    h6 += carry5;
+    h5 -= carry5 << 25;
+
+    carry2 = (h2 + (long) (1 << 25)) >> 26;
+    h3 += carry2;
+    h2 -= carry2 << 26;
+    carry6 = (h6 + (long) (1 << 25)) >> 26;
+    h7 += carry6;
+    h6 -= carry6 << 26;
+
+    carry3 = (h3 + (long) (1 << 24)) >> 25;
+    h4 += carry3;
+    h3 -= carry3 << 25;
+    carry7 = (h7 + (long) (1 << 24)) >> 25;
+    h8 += carry7;
+    h7 -= carry7 << 25;
+
+    carry4 = (h4 + (long) (1 << 25)) >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+    carry8 = (h8 + (long) (1 << 25)) >> 26;
+    h9 += carry8;
+    h8 -= carry8 << 26;
+
+    carry9 = (h9 + (long) (1 << 24)) >> 25;
+    h0 += carry9 * 19;
+    h9 -= carry9 << 25;
+
+    carry0 = (h0 + (long) (1 << 25)) >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+
+    int[] h = new int[10];
+    h[0] = (int) h0;
+    h[1] = (int) h1;
+    h[2] = (int) h2;
+    h[3] = (int) h3;
+    h[4] = (int) h4;
+    h[5] = (int) h5;
+    h[6] = (int) h6;
+    h[7] = (int) h7;
+    h[8] = (int) h8;
+    h[9] = (int) h9;
+    return new Ed25519FieldElement(f, h);
+  }
+
+  /**
+   * $h = 2 * f * f$
+   *
+   * <p>Can overlap $h$ with $f$.
+   *
+   * <p>Preconditions:
+   *
+   * <ul>
+   *   <li>$|f|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc.
+   * </ul>
+   *
+   * <p>Postconditions:
+   *
+   * <ul>
+   *   <li>$|h|$ bounded by $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc.
+   * </ul>
+   *
+   * <p>See {@link #multiply(FieldElement)} for discussion of implementation strategy.
+   *
+   * @return The (reasonably reduced) square of this field element times 2.
+   */
+  public FieldElement squareAndDouble() {
+    int f0 = t[0];
+    int f1 = t[1];
+    int f2 = t[2];
+    int f3 = t[3];
+    int f4 = t[4];
+    int f5 = t[5];
+    int f6 = t[6];
+    int f7 = t[7];
+    int f8 = t[8];
+    int f9 = t[9];
+    int f0_2 = 2 * f0;
+    int f1_2 = 2 * f1;
+    int f2_2 = 2 * f2;
+    int f3_2 = 2 * f3;
+    int f4_2 = 2 * f4;
+    int f5_2 = 2 * f5;
+    int f6_2 = 2 * f6;
+    int f7_2 = 2 * f7;
+    int f5_38 = 38 * f5; /* 1.959375*2^30 */
+    int f6_19 = 19 * f6; /* 1.959375*2^30 */
+    int f7_38 = 38 * f7; /* 1.959375*2^30 */
+    int f8_19 = 19 * f8; /* 1.959375*2^30 */
+    int f9_38 = 38 * f9; /* 1.959375*2^30 */
+    long f0f0 = f0 * (long) f0;
+    long f0f1_2 = f0_2 * (long) f1;
+    long f0f2_2 = f0_2 * (long) f2;
+    long f0f3_2 = f0_2 * (long) f3;
+    long f0f4_2 = f0_2 * (long) f4;
+    long f0f5_2 = f0_2 * (long) f5;
+    long f0f6_2 = f0_2 * (long) f6;
+    long f0f7_2 = f0_2 * (long) f7;
+    long f0f8_2 = f0_2 * (long) f8;
+    long f0f9_2 = f0_2 * (long) f9;
+    long f1f1_2 = f1_2 * (long) f1;
+    long f1f2_2 = f1_2 * (long) f2;
+    long f1f3_4 = f1_2 * (long) f3_2;
+    long f1f4_2 = f1_2 * (long) f4;
+    long f1f5_4 = f1_2 * (long) f5_2;
+    long f1f6_2 = f1_2 * (long) f6;
+    long f1f7_4 = f1_2 * (long) f7_2;
+    long f1f8_2 = f1_2 * (long) f8;
+    long f1f9_76 = f1_2 * (long) f9_38;
+    long f2f2 = f2 * (long) f2;
+    long f2f3_2 = f2_2 * (long) f3;
+    long f2f4_2 = f2_2 * (long) f4;
+    long f2f5_2 = f2_2 * (long) f5;
+    long f2f6_2 = f2_2 * (long) f6;
+    long f2f7_2 = f2_2 * (long) f7;
+    long f2f8_38 = f2_2 * (long) f8_19;
+    long f2f9_38 = f2 * (long) f9_38;
+    long f3f3_2 = f3_2 * (long) f3;
+    long f3f4_2 = f3_2 * (long) f4;
+    long f3f5_4 = f3_2 * (long) f5_2;
+    long f3f6_2 = f3_2 * (long) f6;
+    long f3f7_76 = f3_2 * (long) f7_38;
+    long f3f8_38 = f3_2 * (long) f8_19;
+    long f3f9_76 = f3_2 * (long) f9_38;
+    long f4f4 = f4 * (long) f4;
+    long f4f5_2 = f4_2 * (long) f5;
+    long f4f6_38 = f4_2 * (long) f6_19;
+    long f4f7_38 = f4 * (long) f7_38;
+    long f4f8_38 = f4_2 * (long) f8_19;
+    long f4f9_38 = f4 * (long) f9_38;
+    long f5f5_38 = f5 * (long) f5_38;
+    long f5f6_38 = f5_2 * (long) f6_19;
+    long f5f7_76 = f5_2 * (long) f7_38;
+    long f5f8_38 = f5_2 * (long) f8_19;
+    long f5f9_76 = f5_2 * (long) f9_38;
+    long f6f6_19 = f6 * (long) f6_19;
+    long f6f7_38 = f6 * (long) f7_38;
+    long f6f8_38 = f6_2 * (long) f8_19;
+    long f6f9_38 = f6 * (long) f9_38;
+    long f7f7_38 = f7 * (long) f7_38;
+    long f7f8_38 = f7_2 * (long) f8_19;
+    long f7f9_76 = f7_2 * (long) f9_38;
+    long f8f8_19 = f8 * (long) f8_19;
+    long f8f9_38 = f8 * (long) f9_38;
+    long f9f9_38 = f9 * (long) f9_38;
+    long h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
+    long h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
+    long h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
+    long h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
+    long h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
+    long h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
+    long h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
+    long h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
+    long h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
+    long h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
+    long carry0;
+    long carry1;
+    long carry2;
+    long carry3;
+    long carry4;
+    long carry5;
+    long carry6;
+    long carry7;
+    long carry8;
+    long carry9;
+
+    h0 += h0;
+    h1 += h1;
+    h2 += h2;
+    h3 += h3;
+    h4 += h4;
+    h5 += h5;
+    h6 += h6;
+    h7 += h7;
+    h8 += h8;
+    h9 += h9;
+
+    carry0 = (h0 + (long) (1 << 25)) >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+    carry4 = (h4 + (long) (1 << 25)) >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+
+    carry1 = (h1 + (long) (1 << 24)) >> 25;
+    h2 += carry1;
+    h1 -= carry1 << 25;
+    carry5 = (h5 + (long) (1 << 24)) >> 25;
+    h6 += carry5;
+    h5 -= carry5 << 25;
+
+    carry2 = (h2 + (long) (1 << 25)) >> 26;
+    h3 += carry2;
+    h2 -= carry2 << 26;
+    carry6 = (h6 + (long) (1 << 25)) >> 26;
+    h7 += carry6;
+    h6 -= carry6 << 26;
+
+    carry3 = (h3 + (long) (1 << 24)) >> 25;
+    h4 += carry3;
+    h3 -= carry3 << 25;
+    carry7 = (h7 + (long) (1 << 24)) >> 25;
+    h8 += carry7;
+    h7 -= carry7 << 25;
+
+    carry4 = (h4 + (long) (1 << 25)) >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+    carry8 = (h8 + (long) (1 << 25)) >> 26;
+    h9 += carry8;
+    h8 -= carry8 << 26;
+
+    carry9 = (h9 + (long) (1 << 24)) >> 25;
+    h0 += carry9 * 19;
+    h9 -= carry9 << 25;
+
+    carry0 = (h0 + (long) (1 << 25)) >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+
+    int[] h = new int[10];
+    h[0] = (int) h0;
+    h[1] = (int) h1;
+    h[2] = (int) h2;
+    h[3] = (int) h3;
+    h[4] = (int) h4;
+    h[5] = (int) h5;
+    h[6] = (int) h6;
+    h[7] = (int) h7;
+    h[8] = (int) h8;
+    h[9] = (int) h9;
+    return new Ed25519FieldElement(f, h);
+  }
+
+  /**
+   * Invert this field element.
+   *
+   * <p>The inverse is found via Fermat's little theorem:<br>
+   * $a^p \cong a \mod p$ and therefore $a^{(p-2)} \cong a^{-1} \mod p$
+   *
+   * @return The inverse of this field element.
+   */
+  public FieldElement invert() {
+    FieldElement t0, t1, t2, t3;
+
+    // 2 == 2 * 1
+    t0 = square();
+
+    // 4 == 2 * 2
+    t1 = t0.square();
+
+    // 8 == 2 * 4
+    t1 = t1.square();
+
+    // 9 == 8 + 1
+    t1 = multiply(t1);
+
+    // 11 == 9 + 2
+    t0 = t0.multiply(t1);
+
+    // 22 == 2 * 11
+    t2 = t0.square();
+
+    // 31 == 22 + 9
+    t1 = t1.multiply(t2);
+
+    // 2^6 - 2^1
+    t2 = t1.square();
+
+    // 2^10 - 2^5
+    for (int i = 1; i < 5; ++i) {
+      t2 = t2.square();
+    }
+
+    // 2^10 - 2^0
+    t1 = t2.multiply(t1);
+
+    // 2^11 - 2^1
+    t2 = t1.square();
+
+    // 2^20 - 2^10
+    for (int i = 1; i < 10; ++i) {
+      t2 = t2.square();
+    }
+
+    // 2^20 - 2^0
+    t2 = t2.multiply(t1);
+
+    // 2^21 - 2^1
+    t3 = t2.square();
+
+    // 2^40 - 2^20
+    for (int i = 1; i < 20; ++i) {
+      t3 = t3.square();
+    }
+
+    // 2^40 - 2^0
+    t2 = t3.multiply(t2);
+
+    // 2^41 - 2^1
+    t2 = t2.square();
+
+    // 2^50 - 2^10
+    for (int i = 1; i < 10; ++i) {
+      t2 = t2.square();
+    }
+
+    // 2^50 - 2^0
+    t1 = t2.multiply(t1);
+
+    // 2^51 - 2^1
+    t2 = t1.square();
+
+    // 2^100 - 2^50
+    for (int i = 1; i < 50; ++i) {
+      t2 = t2.square();
+    }
+
+    // 2^100 - 2^0
+    t2 = t2.multiply(t1);
+
+    // 2^101 - 2^1
+    t3 = t2.square();
+
+    // 2^200 - 2^100
+    for (int i = 1; i < 100; ++i) {
+      t3 = t3.square();
+    }
+
+    // 2^200 - 2^0
+    t2 = t3.multiply(t2);
+
+    // 2^201 - 2^1
+    t2 = t2.square();
+
+    // 2^250 - 2^50
+    for (int i = 1; i < 50; ++i) {
+      t2 = t2.square();
+    }
+
+    // 2^250 - 2^0
+    t1 = t2.multiply(t1);
+
+    // 2^251 - 2^1
+    t1 = t1.square();
+
+    // 2^255 - 2^5
+    for (int i = 1; i < 5; ++i) {
+      t1 = t1.square();
+    }
+
+    // 2^255 - 21
+    return t1.multiply(t0);
+  }
+
+  /**
+   * Gets this field element to the power of $(2^{252} - 3)$. This is a helper function for
+   * calculating the square root.
+   *
+   * <p>TODO-CR BR: I think it makes sense to have a sqrt function.
+   *
+   * @return This field element to the power of $(2^{252} - 3)$.
+   */
+  public FieldElement pow22523() {
+    FieldElement t0, t1, t2;
+
+    // 2 == 2 * 1
+    t0 = square();
+
+    // 4 == 2 * 2
+    t1 = t0.square();
+
+    // 8 == 2 * 4
+    t1 = t1.square();
+
+    // z9 = z1*z8
+    t1 = multiply(t1);
+
+    // 11 == 9 + 2
+    t0 = t0.multiply(t1);
+
+    // 22 == 2 * 11
+    t0 = t0.square();
+
+    // 31 == 22 + 9
+    t0 = t1.multiply(t0);
+
+    // 2^6 - 2^1
+    t1 = t0.square();
+
+    // 2^10 - 2^5
+    for (int i = 1; i < 5; ++i) {
+      t1 = t1.square();
+    }
+
+    // 2^10 - 2^0
+    t0 = t1.multiply(t0);
+
+    // 2^11 - 2^1
+    t1 = t0.square();
+
+    // 2^20 - 2^10
+    for (int i = 1; i < 10; ++i) {
+      t1 = t1.square();
+    }
+
+    // 2^20 - 2^0
+    t1 = t1.multiply(t0);
+
+    // 2^21 - 2^1
+    t2 = t1.square();
+
+    // 2^40 - 2^20
+    for (int i = 1; i < 20; ++i) {
+      t2 = t2.square();
+    }
+
+    // 2^40 - 2^0
+    t1 = t2.multiply(t1);
+
+    // 2^41 - 2^1
+    t1 = t1.square();
+
+    // 2^50 - 2^10
+    for (int i = 1; i < 10; ++i) {
+      t1 = t1.square();
+    }
+
+    // 2^50 - 2^0
+    t0 = t1.multiply(t0);
+
+    // 2^51 - 2^1
+    t1 = t0.square();
+
+    // 2^100 - 2^50
+    for (int i = 1; i < 50; ++i) {
+      t1 = t1.square();
+    }
+
+    // 2^100 - 2^0
+    t1 = t1.multiply(t0);
+
+    // 2^101 - 2^1
+    t2 = t1.square();
+
+    // 2^200 - 2^100
+    for (int i = 1; i < 100; ++i) {
+      t2 = t2.square();
+    }
+
+    // 2^200 - 2^0
+    t1 = t2.multiply(t1);
+
+    // 2^201 - 2^1
+    t1 = t1.square();
+
+    // 2^250 - 2^50
+    for (int i = 1; i < 50; ++i) {
+      t1 = t1.square();
+    }
+
+    // 2^250 - 2^0
+    t0 = t1.multiply(t0);
+
+    // 2^251 - 2^1
+    t0 = t0.square();
+
+    // 2^252 - 2^2
+    t0 = t0.square();
+
+    // 2^252 - 3
+    return multiply(t0);
+  }
+
+  /**
+   * Constant-time conditional move. Well, actually it is a conditional copy. Logic is inspired by
+   * the SUPERCOP implementation at:
+   * https://github.com/floodyberry/supercop/blob/master/crypto_sign/ed25519/ref10/fe_cmov.c
+   *
+   * @param val the other field element.
+   * @param b must be 0 or 1, otherwise results are undefined.
+   * @return a copy of this if $b == 0$, or a copy of val if $b == 1$.
+   */
+  @Override
+  public FieldElement cmov(FieldElement val, int b) {
+    Ed25519FieldElement that = (Ed25519FieldElement) val;
+    b = -b;
+    int[] result = new int[10];
+    for (int i = 0; i < 10; i++) {
+      result[i] = this.t[i];
+      int x = this.t[i] ^ that.t[i];
+      x &= b;
+      result[i] ^= x;
+    }
+    return new Ed25519FieldElement(this.f, result);
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(t);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof Ed25519FieldElement)) return false;
+    Ed25519FieldElement fe = (Ed25519FieldElement) obj;
+    return 1 == Utils.equal(toByteArray(), fe.toByteArray());
+  }
+
+  @Override
+  public String toString() {
+    return "[Ed25519FieldElement val=" + Utils.bytesToHex(toByteArray()) + "]";
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519LittleEndianEncoding.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519LittleEndianEncoding.java
new file mode 100644
index 0000000..7c17169
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519LittleEndianEncoding.java
@@ -0,0 +1,278 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ed25519;
+
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.Encoding;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.FieldElement;
+
+/**
+ * Helper class for encoding/decoding from/to the 32 byte representation.
+ *
+ * <p>Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
+ */
+public class Ed25519LittleEndianEncoding extends Encoding {
+  /**
+   * Encodes a given field element in its 32 byte representation. This is done in two steps:
+   *
+   * <ol>
+   *   <li>Reduce the value of the field element modulo $p$.
+   *   <li>Convert the field element to the 32 byte representation.
+   * </ol>
+   *
+   * <p>The idea for the modulo $p$ reduction algorithm is as follows:
+   *
+   * <ul>
+   *   <li>$p = 2^{255} - 19$
+   *   <li>$h = h_0 + 2^{25} * h_1 + 2^{(26+25)} * h_2 + \dots + 2^{230} * h_9$ where $0 \le |h_i|
+   *       \lt 2^{27}$ for all $i=0,\dots,9$.
+   *   <li>$h \cong r \mod p$, i.e. $h = r + q * p$ for some suitable $0 \le r \lt p$ and an integer
+   *       $q$.
+   * </ul>
+   *
+   * <p>Then $q = [2^{-255} * (h + 19 * 2^{-25} * h_9 + 1/2)]$ where $[x] = floor(x)$.
+   *
+   * <p>Proof:
+   *
+   * <p>We begin with some very raw estimation for the bounds of some expressions:
+   *
+   * <p>$$ \begin{equation} |h| \lt 2^{230} * 2^{30} = 2^{260} \Rightarrow |r + q * p| \lt 2^{260}
+   * \Rightarrow |q| \lt 2^{10}. \\ \Rightarrow -1/4 \le a := 19^2 * 2^{-255} * q \lt 1/4. \\ |h -
+   * 2^{230} * h_9| = |h_0 + \dots + 2^{204} * h_8| \lt 2^{204} * 2^{30} = 2^{234}. \\ \Rightarrow
+   * -1/4 \le b := 19 * 2^{-255} * (h - 2^{230} * h_9) \lt 1/4 \end{equation} $$
+   *
+   * <p>Therefore $0 \lt 1/2 - a - b \lt 1$.
+   *
+   * <p>Set $x := r + 19 * 2^{-255} * r + 1/2 - a - b$. Then:
+   *
+   * <p>$$ 0 \le x \lt 255 - 20 + 19 + 1 = 2^{255} \\ \Rightarrow 0 \le 2^{-255} * x \lt 1. $$
+   *
+   * <p>Since $q$ is an integer we have
+   *
+   * <p>$$ [q + 2^{-255} * x] = q \quad (1) $$
+   *
+   * <p>Have a closer look at $x$:
+   *
+   * <p>$$ \begin{align} x &amp;= h - q * (2^{255} - 19) + 19 * 2^{-255} * (h - q * (2^{255} - 19))
+   * + 1/2 - 19^2 * 2^{-255} * q - 19 * 2^{-255} * (h - 2^{230} * h_9) \\ &amp;= h - q * 2^{255} +
+   * 19 * q + 19 * 2^{-255} * h - 19 * q + 19^2 * 2^{-255} * q + 1/2 - 19^2 * 2^{-255} * q - 19 *
+   * 2^{-255} * h + 19 * 2^{-25} * h_9 \\ &amp;= h + 19 * 2^{-25} * h_9 + 1/2 - q^{255}. \end{align}
+   * $$
+   *
+   * <p>Inserting the expression for $x$ into $(1)$ we get the desired expression for $q$.
+   */
+  public byte[] encode(FieldElement x) {
+    int[] h = ((Ed25519FieldElement) x).t;
+    int h0 = h[0];
+    int h1 = h[1];
+    int h2 = h[2];
+    int h3 = h[3];
+    int h4 = h[4];
+    int h5 = h[5];
+    int h6 = h[6];
+    int h7 = h[7];
+    int h8 = h[8];
+    int h9 = h[9];
+    int q;
+    int carry0;
+    int carry1;
+    int carry2;
+    int carry3;
+    int carry4;
+    int carry5;
+    int carry6;
+    int carry7;
+    int carry8;
+    int carry9;
+
+    // Step 1:
+    // Calculate q
+    q = (19 * h9 + (1 << 24)) >> 25;
+    q = (h0 + q) >> 26;
+    q = (h1 + q) >> 25;
+    q = (h2 + q) >> 26;
+    q = (h3 + q) >> 25;
+    q = (h4 + q) >> 26;
+    q = (h5 + q) >> 25;
+    q = (h6 + q) >> 26;
+    q = (h7 + q) >> 25;
+    q = (h8 + q) >> 26;
+    q = (h9 + q) >> 25;
+
+    // r = h - q * p = h - 2^255 * q + 19 * q
+    // First add 19 * q then discard the bit 255
+    h0 += 19 * q;
+
+    carry0 = h0 >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+    carry1 = h1 >> 25;
+    h2 += carry1;
+    h1 -= carry1 << 25;
+    carry2 = h2 >> 26;
+    h3 += carry2;
+    h2 -= carry2 << 26;
+    carry3 = h3 >> 25;
+    h4 += carry3;
+    h3 -= carry3 << 25;
+    carry4 = h4 >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+    carry5 = h5 >> 25;
+    h6 += carry5;
+    h5 -= carry5 << 25;
+    carry6 = h6 >> 26;
+    h7 += carry6;
+    h6 -= carry6 << 26;
+    carry7 = h7 >> 25;
+    h8 += carry7;
+    h7 -= carry7 << 25;
+    carry8 = h8 >> 26;
+    h9 += carry8;
+    h8 -= carry8 << 26;
+    carry9 = h9 >> 25;
+    h9 -= carry9 << 25;
+
+    // Step 2 (straight forward conversion):
+    byte[] s = new byte[32];
+    s[0] = (byte) h0;
+    s[1] = (byte) (h0 >> 8);
+    s[2] = (byte) (h0 >> 16);
+    s[3] = (byte) ((h0 >> 24) | (h1 << 2));
+    s[4] = (byte) (h1 >> 6);
+    s[5] = (byte) (h1 >> 14);
+    s[6] = (byte) ((h1 >> 22) | (h2 << 3));
+    s[7] = (byte) (h2 >> 5);
+    s[8] = (byte) (h2 >> 13);
+    s[9] = (byte) ((h2 >> 21) | (h3 << 5));
+    s[10] = (byte) (h3 >> 3);
+    s[11] = (byte) (h3 >> 11);
+    s[12] = (byte) ((h3 >> 19) | (h4 << 6));
+    s[13] = (byte) (h4 >> 2);
+    s[14] = (byte) (h4 >> 10);
+    s[15] = (byte) (h4 >> 18);
+    s[16] = (byte) h5;
+    s[17] = (byte) (h5 >> 8);
+    s[18] = (byte) (h5 >> 16);
+    s[19] = (byte) ((h5 >> 24) | (h6 << 1));
+    s[20] = (byte) (h6 >> 7);
+    s[21] = (byte) (h6 >> 15);
+    s[22] = (byte) ((h6 >> 23) | (h7 << 3));
+    s[23] = (byte) (h7 >> 5);
+    s[24] = (byte) (h7 >> 13);
+    s[25] = (byte) ((h7 >> 21) | (h8 << 4));
+    s[26] = (byte) (h8 >> 4);
+    s[27] = (byte) (h8 >> 12);
+    s[28] = (byte) ((h8 >> 20) | (h9 << 6));
+    s[29] = (byte) (h9 >> 2);
+    s[30] = (byte) (h9 >> 10);
+    s[31] = (byte) (h9 >> 18);
+    return s;
+  }
+
+  static int load_3(byte[] in, int offset) {
+    int result = in[offset++] & 0xff;
+    result |= (in[offset++] & 0xff) << 8;
+    result |= (in[offset] & 0xff) << 16;
+    return result;
+  }
+
+  static long load_4(byte[] in, int offset) {
+    int result = in[offset++] & 0xff;
+    result |= (in[offset++] & 0xff) << 8;
+    result |= (in[offset++] & 0xff) << 16;
+    result |= in[offset] << 24;
+    return ((long) result) & 0xffffffffL;
+  }
+
+  /**
+   * Decodes a given field element in its 10 byte $2^{25.5}$ representation.
+   *
+   * @param in The 32 byte representation.
+   * @return The field element in its $2^{25.5}$ bit representation.
+   */
+  public FieldElement decode(byte[] in) {
+    long h0 = load_4(in, 0);
+    long h1 = load_3(in, 4) << 6;
+    long h2 = load_3(in, 7) << 5;
+    long h3 = load_3(in, 10) << 3;
+    long h4 = load_3(in, 13) << 2;
+    long h5 = load_4(in, 16);
+    long h6 = load_3(in, 20) << 7;
+    long h7 = load_3(in, 23) << 5;
+    long h8 = load_3(in, 26) << 4;
+    long h9 = (load_3(in, 29) & 0x7FFFFF) << 2;
+    long carry0;
+    long carry1;
+    long carry2;
+    long carry3;
+    long carry4;
+    long carry5;
+    long carry6;
+    long carry7;
+    long carry8;
+    long carry9;
+
+    // Remember: 2^255 congruent 19 modulo p
+    carry9 = (h9 + (long) (1 << 24)) >> 25;
+    h0 += carry9 * 19;
+    h9 -= carry9 << 25;
+    carry1 = (h1 + (long) (1 << 24)) >> 25;
+    h2 += carry1;
+    h1 -= carry1 << 25;
+    carry3 = (h3 + (long) (1 << 24)) >> 25;
+    h4 += carry3;
+    h3 -= carry3 << 25;
+    carry5 = (h5 + (long) (1 << 24)) >> 25;
+    h6 += carry5;
+    h5 -= carry5 << 25;
+    carry7 = (h7 + (long) (1 << 24)) >> 25;
+    h8 += carry7;
+    h7 -= carry7 << 25;
+
+    carry0 = (h0 + (long) (1 << 25)) >> 26;
+    h1 += carry0;
+    h0 -= carry0 << 26;
+    carry2 = (h2 + (long) (1 << 25)) >> 26;
+    h3 += carry2;
+    h2 -= carry2 << 26;
+    carry4 = (h4 + (long) (1 << 25)) >> 26;
+    h5 += carry4;
+    h4 -= carry4 << 26;
+    carry6 = (h6 + (long) (1 << 25)) >> 26;
+    h7 += carry6;
+    h6 -= carry6 << 26;
+    carry8 = (h8 + (long) (1 << 25)) >> 26;
+    h9 += carry8;
+    h8 -= carry8 << 26;
+
+    int[] h = new int[10];
+    h[0] = (int) h0;
+    h[1] = (int) h1;
+    h[2] = (int) h2;
+    h[3] = (int) h3;
+    h[4] = (int) h4;
+    h[5] = (int) h5;
+    h[6] = (int) h6;
+    h[7] = (int) h7;
+    h[8] = (int) h8;
+    h[9] = (int) h9;
+    return new Ed25519FieldElement(f, h);
+  }
+
+  /**
+   * Is the FieldElement negative in this encoding?
+   *
+   * <p>Return true if $x$ is in $\{1,3,5,\dots,q-2\}$<br>
+   * Return false if $x$ is in $\{0,2,4,\dots,q-1\}$
+   *
+   * <p>Preconditions:
+   *
+   * <ul>
+   *   <li>$|x|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25}$, etc.
+   * </ul>
+   *
+   * @return true if $x$ is in $\{1,3,5,\dots,q-2\}$, false otherwise.
+   */
+  public boolean isNegative(FieldElement x) {
+    byte[] s = encode(x);
+    return (s[0] & 1) != 0;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519ScalarOps.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519ScalarOps.java
new file mode 100644
index 0000000..0f9a518
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/math/ed25519/Ed25519ScalarOps.java
@@ -0,0 +1,905 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * <p>To the extent possible under law, the person who associated CC0 with EdDSA-Java has waived all
+ * copyright and related or neighboring rights to EdDSA-Java.
+ *
+ * <p>You should have received a copy of the CC0 legalcode along with this work. If not, see
+ * <https://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ed25519;
+
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ScalarOps;
+
+/**
+ * Class for reducing a huge integer modulo the group order q and doing a combined multiply plus add
+ * plus reduce operation.
+ *
+ * <p>$q = 2^{252} + 27742317777372353535851937790883648493$.
+ *
+ * <p>Reviewed/commented by Bloody Rookie (nemproject@gmx.de)
+ */
+public class Ed25519ScalarOps implements ScalarOps {
+
+  /**
+   * Reduction modulo the group order $q$.
+   *
+   * <p>Input: $s[0]+256*s[1]+\dots+256^{63}*s[63] = s$
+   *
+   * <p>Output: $s[0]+256*s[1]+\dots+256^{31}*s[31] = s \bmod q$ where $q = 2^{252} +
+   * 27742317777372353535851937790883648493$.
+   */
+  public byte[] reduce(byte[] s) {
+    // s0,..., s22 have 21 bits, s23 has 29 bits
+    long s0 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(s, 0);
+    long s1 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 2) >> 5);
+    long s2 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 5) >> 2);
+    long s3 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 7) >> 7);
+    long s4 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 10) >> 4);
+    long s5 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 13) >> 1);
+    long s6 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 15) >> 6);
+    long s7 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 18) >> 3);
+    long s8 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(s, 21);
+    long s9 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 23) >> 5);
+    long s10 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 26) >> 2);
+    long s11 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 28) >> 7);
+    long s12 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 31) >> 4);
+    long s13 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 34) >> 1);
+    long s14 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 36) >> 6);
+    long s15 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 39) >> 3);
+    long s16 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(s, 42);
+    long s17 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 44) >> 5);
+    long s18 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 47) >> 2);
+    long s19 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 49) >> 7);
+    long s20 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 52) >> 4);
+    long s21 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(s, 55) >> 1);
+    long s22 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(s, 57) >> 6);
+    long s23 = (Ed25519LittleEndianEncoding.load_4(s, 60) >> 3);
+    long carry0;
+    long carry1;
+    long carry2;
+    long carry3;
+    long carry4;
+    long carry5;
+    long carry6;
+    long carry7;
+    long carry8;
+    long carry9;
+    long carry10;
+    long carry11;
+    long carry12;
+    long carry13;
+    long carry14;
+    long carry15;
+    long carry16;
+
+    s11 += s23 * 666643;
+    s12 += s23 * 470296;
+    s13 += s23 * 654183;
+    s14 -= s23 * 997805;
+    s15 += s23 * 136657;
+    s16 -= s23 * 683901;
+    // not used again
+    // s23 = 0;
+
+    s10 += s22 * 666643;
+    s11 += s22 * 470296;
+    s12 += s22 * 654183;
+    s13 -= s22 * 997805;
+    s14 += s22 * 136657;
+    s15 -= s22 * 683901;
+    // not used again
+    // s22 = 0;
+
+    s9 += s21 * 666643;
+    s10 += s21 * 470296;
+    s11 += s21 * 654183;
+    s12 -= s21 * 997805;
+    s13 += s21 * 136657;
+    s14 -= s21 * 683901;
+    // not used again
+    // s21 = 0;
+
+    s8 += s20 * 666643;
+    s9 += s20 * 470296;
+    s10 += s20 * 654183;
+    s11 -= s20 * 997805;
+    s12 += s20 * 136657;
+    s13 -= s20 * 683901;
+    // not used again
+    // s20 = 0;
+
+    s7 += s19 * 666643;
+    s8 += s19 * 470296;
+    s9 += s19 * 654183;
+    s10 -= s19 * 997805;
+    s11 += s19 * 136657;
+    s12 -= s19 * 683901;
+    // not used again
+    // s19 = 0;
+
+    s6 += s18 * 666643;
+    s7 += s18 * 470296;
+    s8 += s18 * 654183;
+    s9 -= s18 * 997805;
+    s10 += s18 * 136657;
+    s11 -= s18 * 683901;
+    // not used again
+    // s18 = 0;
+
+    carry6 = (s6 + (1 << 20)) >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry8 = (s8 + (1 << 20)) >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry10 = (s10 + (1 << 20)) >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+    carry12 = (s12 + (1 << 20)) >> 21;
+    s13 += carry12;
+    s12 -= carry12 << 21;
+    carry14 = (s14 + (1 << 20)) >> 21;
+    s15 += carry14;
+    s14 -= carry14 << 21;
+    carry16 = (s16 + (1 << 20)) >> 21;
+    s17 += carry16;
+    s16 -= carry16 << 21;
+
+    carry7 = (s7 + (1 << 20)) >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry9 = (s9 + (1 << 20)) >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    carry11 = (s11 + (1 << 20)) >> 21;
+    s12 += carry11;
+    s11 -= carry11 << 21;
+    carry13 = (s13 + (1 << 20)) >> 21;
+    s14 += carry13;
+    s13 -= carry13 << 21;
+    carry15 = (s15 + (1 << 20)) >> 21;
+    s16 += carry15;
+    s15 -= carry15 << 21;
+
+    s5 += s17 * 666643;
+    s6 += s17 * 470296;
+    s7 += s17 * 654183;
+    s8 -= s17 * 997805;
+    s9 += s17 * 136657;
+    s10 -= s17 * 683901;
+    // not used again
+    // s17 = 0;
+
+    s4 += s16 * 666643;
+    s5 += s16 * 470296;
+    s6 += s16 * 654183;
+    s7 -= s16 * 997805;
+    s8 += s16 * 136657;
+    s9 -= s16 * 683901;
+    // not used again
+    // s16 = 0;
+
+    s3 += s15 * 666643;
+    s4 += s15 * 470296;
+    s5 += s15 * 654183;
+    s6 -= s15 * 997805;
+    s7 += s15 * 136657;
+    s8 -= s15 * 683901;
+    // not used again
+    // s15 = 0;
+
+    s2 += s14 * 666643;
+    s3 += s14 * 470296;
+    s4 += s14 * 654183;
+    s5 -= s14 * 997805;
+    s6 += s14 * 136657;
+    s7 -= s14 * 683901;
+    // not used again
+    // s14 = 0;
+
+    s1 += s13 * 666643;
+    s2 += s13 * 470296;
+    s3 += s13 * 654183;
+    s4 -= s13 * 997805;
+    s5 += s13 * 136657;
+    s6 -= s13 * 683901;
+    // not used again
+    // s13 = 0;
+
+    s0 += s12 * 666643;
+    s1 += s12 * 470296;
+    s2 += s12 * 654183;
+    s3 -= s12 * 997805;
+    s4 += s12 * 136657;
+    s5 -= s12 * 683901;
+    // set below
+    // s12 = 0;
+
+    carry0 = (s0 + (1 << 20)) >> 21;
+    s1 += carry0;
+    s0 -= carry0 << 21;
+    carry2 = (s2 + (1 << 20)) >> 21;
+    s3 += carry2;
+    s2 -= carry2 << 21;
+    carry4 = (s4 + (1 << 20)) >> 21;
+    s5 += carry4;
+    s4 -= carry4 << 21;
+    carry6 = (s6 + (1 << 20)) >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry8 = (s8 + (1 << 20)) >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry10 = (s10 + (1 << 20)) >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+
+    carry1 = (s1 + (1 << 20)) >> 21;
+    s2 += carry1;
+    s1 -= carry1 << 21;
+    carry3 = (s3 + (1 << 20)) >> 21;
+    s4 += carry3;
+    s3 -= carry3 << 21;
+    carry5 = (s5 + (1 << 20)) >> 21;
+    s6 += carry5;
+    s5 -= carry5 << 21;
+    carry7 = (s7 + (1 << 20)) >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry9 = (s9 + (1 << 20)) >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    // carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
+    carry11 = (s11 + (1 << 20)) >> 21;
+    s12 = carry11;
+    s11 -= carry11 << 21;
+
+    s0 += s12 * 666643;
+    s1 += s12 * 470296;
+    s2 += s12 * 654183;
+    s3 -= s12 * 997805;
+    s4 += s12 * 136657;
+    s5 -= s12 * 683901;
+    // set below
+    // s12 = 0;
+
+    carry0 = s0 >> 21;
+    s1 += carry0;
+    s0 -= carry0 << 21;
+    carry1 = s1 >> 21;
+    s2 += carry1;
+    s1 -= carry1 << 21;
+    carry2 = s2 >> 21;
+    s3 += carry2;
+    s2 -= carry2 << 21;
+    carry3 = s3 >> 21;
+    s4 += carry3;
+    s3 -= carry3 << 21;
+    carry4 = s4 >> 21;
+    s5 += carry4;
+    s4 -= carry4 << 21;
+    carry5 = s5 >> 21;
+    s6 += carry5;
+    s5 -= carry5 << 21;
+    carry6 = s6 >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry7 = s7 >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry8 = s8 >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry9 = s9 >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    carry10 = s10 >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+    // carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
+    carry11 = s11 >> 21;
+    s12 = carry11;
+    s11 -= carry11 << 21;
+
+    // TODO-CR BR: Is it really needed to do it TWO times? (it doesn't hurt, just a question).
+    s0 += s12 * 666643;
+    s1 += s12 * 470296;
+    s2 += s12 * 654183;
+    s3 -= s12 * 997805;
+    s4 += s12 * 136657;
+    s5 -= s12 * 683901;
+    // not used again
+    // s12 = 0;
+
+    carry0 = s0 >> 21;
+    s1 += carry0;
+    s0 -= carry0 << 21;
+    carry1 = s1 >> 21;
+    s2 += carry1;
+    s1 -= carry1 << 21;
+    carry2 = s2 >> 21;
+    s3 += carry2;
+    s2 -= carry2 << 21;
+    carry3 = s3 >> 21;
+    s4 += carry3;
+    s3 -= carry3 << 21;
+    carry4 = s4 >> 21;
+    s5 += carry4;
+    s4 -= carry4 << 21;
+    carry5 = s5 >> 21;
+    s6 += carry5;
+    s5 -= carry5 << 21;
+    carry6 = s6 >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry7 = s7 >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry8 = s8 >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry9 = s9 >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    carry10 = s10 >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+
+    // s0, ..., s11 got 21 bits each.
+    byte[] result = new byte[32];
+    result[0] = (byte) s0;
+    result[1] = (byte) (s0 >> 8);
+    result[2] = (byte) ((s0 >> 16) | (s1 << 5));
+    result[3] = (byte) (s1 >> 3);
+    result[4] = (byte) (s1 >> 11);
+    result[5] = (byte) ((s1 >> 19) | (s2 << 2));
+    result[6] = (byte) (s2 >> 6);
+    result[7] = (byte) ((s2 >> 14) | (s3 << 7));
+    result[8] = (byte) (s3 >> 1);
+    result[9] = (byte) (s3 >> 9);
+    result[10] = (byte) ((s3 >> 17) | (s4 << 4));
+    result[11] = (byte) (s4 >> 4);
+    result[12] = (byte) (s4 >> 12);
+    result[13] = (byte) ((s4 >> 20) | (s5 << 1));
+    result[14] = (byte) (s5 >> 7);
+    result[15] = (byte) ((s5 >> 15) | (s6 << 6));
+    result[16] = (byte) (s6 >> 2);
+    result[17] = (byte) (s6 >> 10);
+    result[18] = (byte) ((s6 >> 18) | (s7 << 3));
+    result[19] = (byte) (s7 >> 5);
+    result[20] = (byte) (s7 >> 13);
+    result[21] = (byte) s8;
+    result[22] = (byte) (s8 >> 8);
+    result[23] = (byte) ((s8 >> 16) | (s9 << 5));
+    result[24] = (byte) (s9 >> 3);
+    result[25] = (byte) (s9 >> 11);
+    result[26] = (byte) ((s9 >> 19) | (s10 << 2));
+    result[27] = (byte) (s10 >> 6);
+    result[28] = (byte) ((s10 >> 14) | (s11 << 7));
+    result[29] = (byte) (s11 >> 1);
+    result[30] = (byte) (s11 >> 9);
+    result[31] = (byte) (s11 >> 17);
+    return result;
+  }
+
+  /**
+   * $(ab+c) \bmod q$
+   *
+   * <p>Input:
+   *
+   * <ul>
+   *   <li>$a[0]+256*a[1]+\dots+256^{31}*a[31] = a$
+   *   <li>$b[0]+256*b[1]+\dots+256^{31}*b[31] = b$
+   *   <li>$c[0]+256*c[1]+\dots+256^{31}*c[31] = c$
+   * </ul>
+   *
+   * <p>Output: $result[0]+256*result[1]+\dots+256^{31}*result[31] = (ab+c) \bmod q$ where $q =
+   * 2^{252} + 27742317777372353535851937790883648493$.
+   *
+   * <p>See the comments in {@link #reduce(byte[])} for an explanation of the algorithm.
+   */
+  public byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c) {
+    long a0 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(a, 0);
+    long a1 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(a, 2) >> 5);
+    long a2 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(a, 5) >> 2);
+    long a3 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(a, 7) >> 7);
+    long a4 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(a, 10) >> 4);
+    long a5 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(a, 13) >> 1);
+    long a6 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(a, 15) >> 6);
+    long a7 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(a, 18) >> 3);
+    long a8 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(a, 21);
+    long a9 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(a, 23) >> 5);
+    long a10 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(a, 26) >> 2);
+    long a11 = (Ed25519LittleEndianEncoding.load_4(a, 28) >> 7);
+    long b0 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(b, 0);
+    long b1 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(b, 2) >> 5);
+    long b2 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(b, 5) >> 2);
+    long b3 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(b, 7) >> 7);
+    long b4 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(b, 10) >> 4);
+    long b5 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(b, 13) >> 1);
+    long b6 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(b, 15) >> 6);
+    long b7 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(b, 18) >> 3);
+    long b8 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(b, 21);
+    long b9 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(b, 23) >> 5);
+    long b10 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(b, 26) >> 2);
+    long b11 = (Ed25519LittleEndianEncoding.load_4(b, 28) >> 7);
+    long c0 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(c, 0);
+    long c1 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(c, 2) >> 5);
+    long c2 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(c, 5) >> 2);
+    long c3 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(c, 7) >> 7);
+    long c4 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(c, 10) >> 4);
+    long c5 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(c, 13) >> 1);
+    long c6 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(c, 15) >> 6);
+    long c7 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(c, 18) >> 3);
+    long c8 = 0x1FFFFF & Ed25519LittleEndianEncoding.load_3(c, 21);
+    long c9 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_4(c, 23) >> 5);
+    long c10 = 0x1FFFFF & (Ed25519LittleEndianEncoding.load_3(c, 26) >> 2);
+    long c11 = (Ed25519LittleEndianEncoding.load_4(c, 28) >> 7);
+    long s0;
+    long s1;
+    long s2;
+    long s3;
+    long s4;
+    long s5;
+    long s6;
+    long s7;
+    long s8;
+    long s9;
+    long s10;
+    long s11;
+    long s12;
+    long s13;
+    long s14;
+    long s15;
+    long s16;
+    long s17;
+    long s18;
+    long s19;
+    long s20;
+    long s21;
+    long s22;
+    long s23;
+    long carry0;
+    long carry1;
+    long carry2;
+    long carry3;
+    long carry4;
+    long carry5;
+    long carry6;
+    long carry7;
+    long carry8;
+    long carry9;
+    long carry10;
+    long carry11;
+    long carry12;
+    long carry13;
+    long carry14;
+    long carry15;
+    long carry16;
+    long carry17;
+    long carry18;
+    long carry19;
+    long carry20;
+    long carry21;
+    long carry22;
+
+    s0 = c0 + a0 * b0;
+    s1 = c1 + a0 * b1 + a1 * b0;
+    s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
+    s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
+    s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
+    s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
+    s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
+    s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0;
+    s8 =
+        c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1
+            + a8 * b0;
+    s9 =
+        c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1
+            + a9 * b0;
+    s10 =
+        c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3
+            + a8 * b2 + a9 * b1 + a10 * b0;
+    s11 =
+        c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4
+            + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
+    s12 =
+        a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3
+            + a10 * b2 + a11 * b1;
+    s13 =
+        a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3
+            + a11 * b2;
+    s14 =
+        a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3;
+    s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4;
+    s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
+    s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
+    s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
+    s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
+    s20 = a9 * b11 + a10 * b10 + a11 * b9;
+    s21 = a10 * b11 + a11 * b10;
+    s22 = a11 * b11;
+    // set below
+    // s23 = 0;
+
+    carry0 = (s0 + (1 << 20)) >> 21;
+    s1 += carry0;
+    s0 -= carry0 << 21;
+    carry2 = (s2 + (1 << 20)) >> 21;
+    s3 += carry2;
+    s2 -= carry2 << 21;
+    carry4 = (s4 + (1 << 20)) >> 21;
+    s5 += carry4;
+    s4 -= carry4 << 21;
+    carry6 = (s6 + (1 << 20)) >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry8 = (s8 + (1 << 20)) >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry10 = (s10 + (1 << 20)) >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+    carry12 = (s12 + (1 << 20)) >> 21;
+    s13 += carry12;
+    s12 -= carry12 << 21;
+    carry14 = (s14 + (1 << 20)) >> 21;
+    s15 += carry14;
+    s14 -= carry14 << 21;
+    carry16 = (s16 + (1 << 20)) >> 21;
+    s17 += carry16;
+    s16 -= carry16 << 21;
+    carry18 = (s18 + (1 << 20)) >> 21;
+    s19 += carry18;
+    s18 -= carry18 << 21;
+    carry20 = (s20 + (1 << 20)) >> 21;
+    s21 += carry20;
+    s20 -= carry20 << 21;
+    // carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21;
+    carry22 = (s22 + (1 << 20)) >> 21;
+    s23 = carry22;
+    s22 -= carry22 << 21;
+
+    carry1 = (s1 + (1 << 20)) >> 21;
+    s2 += carry1;
+    s1 -= carry1 << 21;
+    carry3 = (s3 + (1 << 20)) >> 21;
+    s4 += carry3;
+    s3 -= carry3 << 21;
+    carry5 = (s5 + (1 << 20)) >> 21;
+    s6 += carry5;
+    s5 -= carry5 << 21;
+    carry7 = (s7 + (1 << 20)) >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry9 = (s9 + (1 << 20)) >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    carry11 = (s11 + (1 << 20)) >> 21;
+    s12 += carry11;
+    s11 -= carry11 << 21;
+    carry13 = (s13 + (1 << 20)) >> 21;
+    s14 += carry13;
+    s13 -= carry13 << 21;
+    carry15 = (s15 + (1 << 20)) >> 21;
+    s16 += carry15;
+    s15 -= carry15 << 21;
+    carry17 = (s17 + (1 << 20)) >> 21;
+    s18 += carry17;
+    s17 -= carry17 << 21;
+    carry19 = (s19 + (1 << 20)) >> 21;
+    s20 += carry19;
+    s19 -= carry19 << 21;
+    carry21 = (s21 + (1 << 20)) >> 21;
+    s22 += carry21;
+    s21 -= carry21 << 21;
+
+    s11 += s23 * 666643;
+    s12 += s23 * 470296;
+    s13 += s23 * 654183;
+    s14 -= s23 * 997805;
+    s15 += s23 * 136657;
+    s16 -= s23 * 683901;
+    // not used again
+    // s23 = 0;
+
+    s10 += s22 * 666643;
+    s11 += s22 * 470296;
+    s12 += s22 * 654183;
+    s13 -= s22 * 997805;
+    s14 += s22 * 136657;
+    s15 -= s22 * 683901;
+    // not used again
+    // s22 = 0;
+
+    s9 += s21 * 666643;
+    s10 += s21 * 470296;
+    s11 += s21 * 654183;
+    s12 -= s21 * 997805;
+    s13 += s21 * 136657;
+    s14 -= s21 * 683901;
+    // not used again
+    // s21 = 0;
+
+    s8 += s20 * 666643;
+    s9 += s20 * 470296;
+    s10 += s20 * 654183;
+    s11 -= s20 * 997805;
+    s12 += s20 * 136657;
+    s13 -= s20 * 683901;
+    // not used again
+    // s20 = 0;
+
+    s7 += s19 * 666643;
+    s8 += s19 * 470296;
+    s9 += s19 * 654183;
+    s10 -= s19 * 997805;
+    s11 += s19 * 136657;
+    s12 -= s19 * 683901;
+    // not used again
+    // s19 = 0;
+
+    s6 += s18 * 666643;
+    s7 += s18 * 470296;
+    s8 += s18 * 654183;
+    s9 -= s18 * 997805;
+    s10 += s18 * 136657;
+    s11 -= s18 * 683901;
+    // not used again
+    // s18 = 0;
+
+    carry6 = (s6 + (1 << 20)) >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry8 = (s8 + (1 << 20)) >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry10 = (s10 + (1 << 20)) >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+    carry12 = (s12 + (1 << 20)) >> 21;
+    s13 += carry12;
+    s12 -= carry12 << 21;
+    carry14 = (s14 + (1 << 20)) >> 21;
+    s15 += carry14;
+    s14 -= carry14 << 21;
+    carry16 = (s16 + (1 << 20)) >> 21;
+    s17 += carry16;
+    s16 -= carry16 << 21;
+
+    carry7 = (s7 + (1 << 20)) >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry9 = (s9 + (1 << 20)) >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    carry11 = (s11 + (1 << 20)) >> 21;
+    s12 += carry11;
+    s11 -= carry11 << 21;
+    carry13 = (s13 + (1 << 20)) >> 21;
+    s14 += carry13;
+    s13 -= carry13 << 21;
+    carry15 = (s15 + (1 << 20)) >> 21;
+    s16 += carry15;
+    s15 -= carry15 << 21;
+
+    s5 += s17 * 666643;
+    s6 += s17 * 470296;
+    s7 += s17 * 654183;
+    s8 -= s17 * 997805;
+    s9 += s17 * 136657;
+    s10 -= s17 * 683901;
+    // not used again
+    // s17 = 0;
+
+    s4 += s16 * 666643;
+    s5 += s16 * 470296;
+    s6 += s16 * 654183;
+    s7 -= s16 * 997805;
+    s8 += s16 * 136657;
+    s9 -= s16 * 683901;
+    // not used again
+    // s16 = 0;
+
+    s3 += s15 * 666643;
+    s4 += s15 * 470296;
+    s5 += s15 * 654183;
+    s6 -= s15 * 997805;
+    s7 += s15 * 136657;
+    s8 -= s15 * 683901;
+    // not used again
+    // s15 = 0;
+
+    s2 += s14 * 666643;
+    s3 += s14 * 470296;
+    s4 += s14 * 654183;
+    s5 -= s14 * 997805;
+    s6 += s14 * 136657;
+    s7 -= s14 * 683901;
+    // not used again
+    // s14 = 0;
+
+    s1 += s13 * 666643;
+    s2 += s13 * 470296;
+    s3 += s13 * 654183;
+    s4 -= s13 * 997805;
+    s5 += s13 * 136657;
+    s6 -= s13 * 683901;
+    // not used again
+    // s13 = 0;
+
+    s0 += s12 * 666643;
+    s1 += s12 * 470296;
+    s2 += s12 * 654183;
+    s3 -= s12 * 997805;
+    s4 += s12 * 136657;
+    s5 -= s12 * 683901;
+    // set below
+    // s12 = 0;
+
+    carry0 = (s0 + (1 << 20)) >> 21;
+    s1 += carry0;
+    s0 -= carry0 << 21;
+    carry2 = (s2 + (1 << 20)) >> 21;
+    s3 += carry2;
+    s2 -= carry2 << 21;
+    carry4 = (s4 + (1 << 20)) >> 21;
+    s5 += carry4;
+    s4 -= carry4 << 21;
+    carry6 = (s6 + (1 << 20)) >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry8 = (s8 + (1 << 20)) >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry10 = (s10 + (1 << 20)) >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+
+    carry1 = (s1 + (1 << 20)) >> 21;
+    s2 += carry1;
+    s1 -= carry1 << 21;
+    carry3 = (s3 + (1 << 20)) >> 21;
+    s4 += carry3;
+    s3 -= carry3 << 21;
+    carry5 = (s5 + (1 << 20)) >> 21;
+    s6 += carry5;
+    s5 -= carry5 << 21;
+    carry7 = (s7 + (1 << 20)) >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry9 = (s9 + (1 << 20)) >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    // carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
+    carry11 = (s11 + (1 << 20)) >> 21;
+    s12 = carry11;
+    s11 -= carry11 << 21;
+
+    s0 += s12 * 666643;
+    s1 += s12 * 470296;
+    s2 += s12 * 654183;
+    s3 -= s12 * 997805;
+    s4 += s12 * 136657;
+    s5 -= s12 * 683901;
+    // set below
+    // s12 = 0;
+
+    carry0 = s0 >> 21;
+    s1 += carry0;
+    s0 -= carry0 << 21;
+    carry1 = s1 >> 21;
+    s2 += carry1;
+    s1 -= carry1 << 21;
+    carry2 = s2 >> 21;
+    s3 += carry2;
+    s2 -= carry2 << 21;
+    carry3 = s3 >> 21;
+    s4 += carry3;
+    s3 -= carry3 << 21;
+    carry4 = s4 >> 21;
+    s5 += carry4;
+    s4 -= carry4 << 21;
+    carry5 = s5 >> 21;
+    s6 += carry5;
+    s5 -= carry5 << 21;
+    carry6 = s6 >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry7 = s7 >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry8 = s8 >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry9 = s9 >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    carry10 = s10 >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+    // carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
+    carry11 = s11 >> 21;
+    s12 = carry11;
+    s11 -= carry11 << 21;
+
+    s0 += s12 * 666643;
+    s1 += s12 * 470296;
+    s2 += s12 * 654183;
+    s3 -= s12 * 997805;
+    s4 += s12 * 136657;
+    s5 -= s12 * 683901;
+    // not used again
+    // s12 = 0;
+
+    carry0 = s0 >> 21;
+    s1 += carry0;
+    s0 -= carry0 << 21;
+    carry1 = s1 >> 21;
+    s2 += carry1;
+    s1 -= carry1 << 21;
+    carry2 = s2 >> 21;
+    s3 += carry2;
+    s2 -= carry2 << 21;
+    carry3 = s3 >> 21;
+    s4 += carry3;
+    s3 -= carry3 << 21;
+    carry4 = s4 >> 21;
+    s5 += carry4;
+    s4 -= carry4 << 21;
+    carry5 = s5 >> 21;
+    s6 += carry5;
+    s5 -= carry5 << 21;
+    carry6 = s6 >> 21;
+    s7 += carry6;
+    s6 -= carry6 << 21;
+    carry7 = s7 >> 21;
+    s8 += carry7;
+    s7 -= carry7 << 21;
+    carry8 = s8 >> 21;
+    s9 += carry8;
+    s8 -= carry8 << 21;
+    carry9 = s9 >> 21;
+    s10 += carry9;
+    s9 -= carry9 << 21;
+    carry10 = s10 >> 21;
+    s11 += carry10;
+    s10 -= carry10 << 21;
+
+    byte[] result = new byte[32];
+    result[0] = (byte) s0;
+    result[1] = (byte) (s0 >> 8);
+    result[2] = (byte) ((s0 >> 16) | (s1 << 5));
+    result[3] = (byte) (s1 >> 3);
+    result[4] = (byte) (s1 >> 11);
+    result[5] = (byte) ((s1 >> 19) | (s2 << 2));
+    result[6] = (byte) (s2 >> 6);
+    result[7] = (byte) ((s2 >> 14) | (s3 << 7));
+    result[8] = (byte) (s3 >> 1);
+    result[9] = (byte) (s3 >> 9);
+    result[10] = (byte) ((s3 >> 17) | (s4 << 4));
+    result[11] = (byte) (s4 >> 4);
+    result[12] = (byte) (s4 >> 12);
+    result[13] = (byte) ((s4 >> 20) | (s5 << 1));
+    result[14] = (byte) (s5 >> 7);
+    result[15] = (byte) ((s5 >> 15) | (s6 << 6));
+    result[16] = (byte) (s6 >> 2);
+    result[17] = (byte) (s6 >> 10);
+    result[18] = (byte) ((s6 >> 18) | (s7 << 3));
+    result[19] = (byte) (s7 >> 5);
+    result[20] = (byte) (s7 >> 13);
+    result[21] = (byte) s8;
+    result[22] = (byte) (s8 >> 8);
+    result[23] = (byte) ((s8 >> 16) | (s9 << 5));
+    result[24] = (byte) (s9 >> 3);
+    result[25] = (byte) (s9 >> 11);
+    result[26] = (byte) ((s9 >> 19) | (s10 << 2));
+    result[27] = (byte) (s10 >> 6);
+    result[28] = (byte) ((s10 >> 14) | (s11 << 7));
+    result[29] = (byte) (s11 >> 1);
+    result[30] = (byte) (s11 >> 9);
+    result[31] = (byte) (s11 >> 17);
+    return result;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSANamedCurveSpec.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSANamedCurveSpec.java
new file mode 100644
index 0000000..69af3b6
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSANamedCurveSpec.java
@@ -0,0 +1,25 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.spec;
+
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.Curve;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.GroupElement;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ScalarOps;
+
+/**
+ * EdDSA Curve specification that can also be referred to by name.
+ *
+ * @author str4d
+ */
+public class EdDSANamedCurveSpec extends EdDSAParameterSpec {
+  private static final long serialVersionUID = -4080022735829727073L;
+  private final String name;
+
+  public EdDSANamedCurveSpec(
+      String name, Curve curve, String hashAlgo, ScalarOps sc, GroupElement B) {
+    super(curve, hashAlgo, sc, B);
+    this.name = name;
+  }
+
+  public String getName() {
+    return name;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSANamedCurveTable.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSANamedCurveTable.java
new file mode 100644
index 0000000..f15c338
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSANamedCurveTable.java
@@ -0,0 +1,63 @@
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.spec;
+
+import java.util.HashMap;
+import java.util.Locale;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.Utils;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.Curve;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.Field;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ed25519.Ed25519LittleEndianEncoding;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ed25519.Ed25519ScalarOps;
+
+/**
+ * The named EdDSA curves.
+ *
+ * @author str4d
+ */
+public class EdDSANamedCurveTable {
+  public static final String ED_25519 = "Ed25519";
+
+  private static final Field ed25519field =
+      new Field(
+          256, // b
+          Utils.hexToBytes("edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"), // q
+          new Ed25519LittleEndianEncoding());
+
+  private static final Curve ed25519curve =
+      new Curve(
+          ed25519field,
+          Utils.hexToBytes("a3785913ca4deb75abd841414d0a700098e879777940c78c73fe6f2bee6c0352"), // d
+          ed25519field.fromByteArray(
+              Utils.hexToBytes(
+                  "b0a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b"))); // I
+
+  public static final EdDSANamedCurveSpec ED_25519_CURVE_SPEC =
+      new EdDSANamedCurveSpec(
+          ED_25519,
+          ed25519curve,
+          "SHA-512", // H
+          new Ed25519ScalarOps(), // l
+          ed25519curve.createPoint( // B
+              Utils.hexToBytes("5866666666666666666666666666666666666666666666666666666666666666"),
+              true)); // Precompute tables for B
+
+  private static volatile HashMap<String, EdDSANamedCurveSpec> curves = new HashMap<>();
+
+  private static synchronized void putCurve(String name, EdDSANamedCurveSpec curve) {
+    HashMap<String, EdDSANamedCurveSpec> newCurves = new HashMap<>(curves);
+    newCurves.put(name, curve);
+    curves = newCurves;
+  }
+
+  public static void defineCurve(EdDSANamedCurveSpec curve) {
+    putCurve(curve.getName().toLowerCase(Locale.ENGLISH), curve);
+  }
+
+  static {
+    // RFC 8032
+    defineCurve(ED_25519_CURVE_SPEC);
+  }
+
+  public static EdDSANamedCurveSpec getByName(String name) {
+    return curves.get(name.toLowerCase(Locale.ENGLISH));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSAParameterSpec.java b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSAParameterSpec.java
new file mode 100644
index 0000000..0fa7df9
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/authentication/standard/ed25519/spec/EdDSAParameterSpec.java
@@ -0,0 +1,84 @@
+/**
+ * EdDSA-Java by str4d
+ *
+ * <p>To the extent possible under law, the person who associated CC0 with EdDSA-Java has waived all
+ * copyright and related or neighboring rights to EdDSA-Java.
+ *
+ * <p>You should have received a copy of the CC0 legalcode along with this work. If not, see
+ * <https://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+package org.mariadb.jdbc.plugin.authentication.standard.ed25519.spec;
+
+import java.io.Serializable;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.Curve;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.GroupElement;
+import org.mariadb.jdbc.plugin.authentication.standard.ed25519.math.ScalarOps;
+
+/**
+ * Parameter specification for an EdDSA algorithm.
+ *
+ * @author str4d
+ */
+public class EdDSAParameterSpec implements AlgorithmParameterSpec, Serializable {
+  private static final long serialVersionUID = 8274987108472012L;
+  private final Curve curve;
+  private final String hashAlgo;
+  private final ScalarOps sc;
+  private final GroupElement B;
+
+  /**
+   * @param curve the curve
+   * @param hashAlgo the JCA string for the hash algorithm
+   * @param sc the parameter L represented as ScalarOps
+   * @param B the parameter B
+   * @throws IllegalArgumentException if hash algorithm is unsupported or length is wrong
+   */
+  public EdDSAParameterSpec(Curve curve, String hashAlgo, ScalarOps sc, GroupElement B) {
+    try {
+      MessageDigest hash = MessageDigest.getInstance(hashAlgo);
+      // EdDSA hash function must produce 2b-bit output
+      if (curve.getField().getb() / 4 != hash.getDigestLength())
+        throw new IllegalArgumentException("Hash output is not 2b-bit");
+    } catch (NoSuchAlgorithmException e) {
+      throw new IllegalArgumentException("Unsupported hash algorithm");
+    }
+
+    this.curve = curve;
+    this.hashAlgo = hashAlgo;
+    this.sc = sc;
+    this.B = B;
+  }
+
+  public Curve getCurve() {
+    return curve;
+  }
+
+  public String getHashAlgorithm() {
+    return hashAlgo;
+  }
+
+  /**
+   * @return the base (generator)
+   */
+  public GroupElement getB() {
+    return B;
+  }
+
+  @Override
+  public int hashCode() {
+    return hashAlgo.hashCode() ^ curve.hashCode() ^ B.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) return true;
+    if (!(o instanceof EdDSAParameterSpec)) return false;
+    EdDSAParameterSpec s = (EdDSAParameterSpec) o;
+    return hashAlgo.equals(s.getHashAlgorithm())
+        && curve.equals(s.getCurve())
+        && B.equals(s.getB());
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/BigDecimalCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/BigDecimalCodec.java
new file mode 100644
index 0000000..41664f2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/BigDecimalCodec.java
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Big decimal codec */
+public class BigDecimalCodec implements Codec<BigDecimal> {
+
+  /** default instance */
+  public static final BigDecimalCodec INSTANCE = new BigDecimalCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.BIGINT,
+          DataType.BIT,
+          DataType.DECIMAL,
+          DataType.OLDDECIMAL,
+          DataType.YEAR,
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return BigDecimal.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(BigDecimal.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof BigDecimal;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public BigDecimal decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    switch (column.getType()) {
+      case TINYINT:
+      case SMALLINT:
+      case MEDIUMINT:
+      case INTEGER:
+      case BIGINT:
+      case FLOAT:
+      case DOUBLE:
+      case DECIMAL:
+      case OLDDECIMAL:
+      case YEAR:
+        return new BigDecimal(buf.readAscii(length));
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as BigDecimal", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case VARCHAR:
+      case VARSTRING:
+      case STRING:
+        String str = buf.readString(length);
+        try {
+          return new BigDecimal(str);
+        } catch (NumberFormatException nfe) {
+          throw new SQLDataException(
+              String.format("value '%s' cannot be decoded as BigDecimal", str));
+        }
+
+      case BIT:
+        long result = 0;
+        for (int i = 0; i < length; i++) {
+          byte b = buf.readByte();
+          result = (result << 8) + (b & 0xff);
+        }
+        return BigDecimal.valueOf(result);
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as BigDecimal", column.getType()));
+    }
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public BigDecimal decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+
+    switch (column.getType()) {
+      case TINYINT:
+        if (!column.isSigned()) {
+          return BigDecimal.valueOf(buf.readUnsignedByte());
+        }
+        return BigDecimal.valueOf((int) buf.readByte());
+
+      case YEAR:
+      case SMALLINT:
+        if (!column.isSigned()) {
+          return BigDecimal.valueOf(buf.readUnsignedShort());
+        }
+        return BigDecimal.valueOf((int) buf.readShort());
+
+      case MEDIUMINT:
+        if (!column.isSigned()) {
+          int val = buf.readUnsignedMedium();
+          buf.skip();
+          return BigDecimal.valueOf(val);
+        }
+        return BigDecimal.valueOf(buf.readInt());
+
+      case INTEGER:
+        if (!column.isSigned()) {
+          return BigDecimal.valueOf(buf.readUnsignedInt());
+        }
+        return BigDecimal.valueOf(buf.readInt());
+
+      case BIGINT:
+        BigInteger val = getBigInteger(buf, column);
+        return new BigDecimal(String.valueOf(val))
+            .setScale(column.getDecimals(), RoundingMode.CEILING);
+
+      case FLOAT:
+        return BigDecimal.valueOf(buf.readFloat());
+
+      case DOUBLE:
+        return BigDecimal.valueOf(buf.readDouble());
+
+      case BIT:
+        long result = 0;
+        for (int i = 0; i < length; i++) {
+          byte b = buf.readByte();
+          result = (result << 8) + (b & 0xff);
+        }
+        return BigDecimal.valueOf(result);
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as BigDecimal", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if has a collation (this is TEXT column)
+
+      case VARCHAR:
+      case VARSTRING:
+      case STRING:
+      case DECIMAL:
+      case OLDDECIMAL:
+        String str = buf.readString(length);
+        try {
+          return new BigDecimal(str);
+        } catch (NumberFormatException nfe) {
+          throw new SQLDataException(
+              String.format("value '%s' cannot be decoded as BigDecimal", str));
+        }
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as BigDecimal", column.getType()));
+    }
+  }
+
+  static BigInteger getBigInteger(ReadableByteBuf buf, ColumnDecoder column) {
+    BigInteger val;
+    if (column.isSigned()) {
+      val = BigInteger.valueOf(buf.readLong());
+    } else {
+      // need BIG ENDIAN, so reverse order
+      byte[] bb = new byte[8];
+      for (int i = 7; i >= 0; i--) {
+        bb[i] = buf.readByte();
+      }
+      val = new BigInteger(1, bb);
+    }
+    return val;
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long length)
+      throws IOException {
+    encoder.writeAscii(((BigDecimal) value).toPlainString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    String asciiFormat = ((BigDecimal) value).toPlainString();
+    encoder.writeLength(asciiFormat.length());
+    encoder.writeAscii(asciiFormat);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DECIMAL.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/BigIntegerCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/BigIntegerCodec.java
new file mode 100644
index 0000000..1f59e26
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/BigIntegerCodec.java
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** BigInteger codec */
+public class BigIntegerCodec implements Codec<BigInteger> {
+
+  /** default instance */
+  public static final BigIntegerCodec INSTANCE = new BigIntegerCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.BIGINT,
+          DataType.YEAR,
+          DataType.DOUBLE,
+          DataType.DECIMAL,
+          DataType.OLDDECIMAL,
+          DataType.FLOAT,
+          DataType.BIT,
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return BigInteger.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(BigInteger.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof BigInteger;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public BigInteger decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+
+    switch (column.getType()) {
+      case FLOAT:
+      case DOUBLE:
+      case DECIMAL:
+      case OLDDECIMAL:
+        return new BigDecimal(buf.readAscii(length)).toBigInteger();
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as BigInteger", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case VARCHAR:
+      case VARSTRING:
+      case STRING:
+        String str2 = buf.readString(length);
+        try {
+          return new BigDecimal(str2).toBigInteger();
+        } catch (NumberFormatException nfe) {
+          throw new SQLDataException(
+              String.format("value '%s' cannot be decoded as BigInteger", str2));
+        }
+
+      case BIT:
+        long result = 0;
+        for (int i = 0; i < length; i++) {
+          byte b = buf.readByte();
+          result = (result << 8) + (b & 0xff);
+        }
+        return BigInteger.valueOf(result);
+
+      case TINYINT:
+      case SMALLINT:
+      case MEDIUMINT:
+      case INTEGER:
+      case BIGINT:
+      case YEAR:
+        return new BigInteger(buf.readAscii(length));
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as BigInteger", column.getType()));
+    }
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public BigInteger decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+
+    switch (column.getType()) {
+      case BIT:
+        long result = 0;
+        for (int i = 0; i < length; i++) {
+          byte b = buf.readByte();
+          result = (result << 8) + (b & 0xff);
+        }
+        return BigInteger.valueOf(result);
+      case TINYINT:
+        if (!column.isSigned()) {
+          return BigInteger.valueOf(buf.readUnsignedByte());
+        }
+        return BigInteger.valueOf((int) buf.readByte());
+
+      case YEAR:
+      case SMALLINT:
+        if (!column.isSigned()) {
+          return BigInteger.valueOf(buf.readUnsignedShort());
+        }
+        return BigInteger.valueOf((int) buf.readShort());
+
+      case MEDIUMINT:
+        if (!column.isSigned()) {
+          int val = buf.readUnsignedMedium();
+          buf.skip();
+          return BigInteger.valueOf(val);
+        }
+        return BigInteger.valueOf(buf.readInt());
+
+      case INTEGER:
+        if (!column.isSigned()) {
+          return BigInteger.valueOf(buf.readUnsignedInt());
+        }
+        return BigInteger.valueOf(buf.readInt());
+
+      case FLOAT:
+        return BigDecimal.valueOf(buf.readFloat()).toBigInteger();
+
+      case DOUBLE:
+        return BigDecimal.valueOf(buf.readDouble()).toBigInteger();
+
+      case DECIMAL:
+        return new BigDecimal(buf.readAscii(length)).toBigInteger();
+
+      case BIGINT:
+        if (column.isSigned()) return BigInteger.valueOf(buf.readLong());
+
+        // need BIG ENDIAN, so reverse order
+        byte[] bb = new byte[8];
+        for (int i = 7; i >= 0; i--) {
+          bb[i] = buf.readByte();
+        }
+        return new BigInteger(1, bb);
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as BigInteger", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case VARCHAR:
+      case VARSTRING:
+      case STRING:
+        String str = buf.readString(length);
+        try {
+          return new BigInteger(str);
+        } catch (NumberFormatException nfe) {
+          throw new SQLDataException(
+              String.format("value '%s' cannot be decoded as BigInteger", str));
+        }
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as BigInteger", column.getType()));
+    }
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long length)
+      throws IOException {
+    encoder.writeAscii(value.toString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    String asciiFormat = value.toString();
+    encoder.writeLength(asciiFormat.length());
+    encoder.writeAscii(asciiFormat);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DECIMAL.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/BitSetCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/BitSetCodec.java
new file mode 100644
index 0000000..6999f5a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/BitSetCodec.java
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.util.BitSet;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** BitSet Codec */
+public class BitSetCodec implements Codec<BitSet> {
+
+  /** default instance */
+  public static final BitSetCodec INSTANCE = new BitSetCodec();
+
+  /**
+   * decode from mysql packet value to BitSet
+   *
+   * @param buf mysql packet buffer
+   * @param length encoded length
+   * @return BitSet value
+   */
+  public static BitSet parseBit(ReadableByteBuf buf, int length) {
+    byte[] arr = new byte[length];
+    buf.readBytes(arr);
+    revertOrder(arr);
+    return BitSet.valueOf(arr);
+  }
+
+  /**
+   * Revert byte array order
+   *
+   * @param array array to revert
+   */
+  public static void revertOrder(byte[] array) {
+    int i = 0;
+    int j = array.length - 1;
+    byte tmp;
+    while (j > i) {
+      tmp = array[j];
+      array[j] = array[i];
+      array[i] = tmp;
+      j--;
+      i++;
+    }
+  }
+
+  public String className() {
+    return BitSet.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.BIT && type.isAssignableFrom(BitSet.class);
+  }
+
+  @Override
+  public BitSet decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) {
+    return parseBit(buf, length);
+  }
+
+  @Override
+  public BitSet decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) {
+    return parseBit(buf, length);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof BitSet;
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long length)
+      throws IOException {
+    byte[] bytes = ((BitSet) value).toByteArray();
+    revertOrder(bytes);
+
+    StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE + 3);
+    sb.append("b'");
+    for (int i = 0; i < Byte.SIZE * bytes.length; i++)
+      sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
+    sb.append("'");
+    encoder.writeAscii(sb.toString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    byte[] bytes = ((BitSet) value).toByteArray();
+    revertOrder(bytes);
+    encoder.writeLength(bytes.length);
+    encoder.writeBytes(bytes);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/BlobCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/BlobCodec.java
new file mode 100644
index 0000000..65b7b8b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/BlobCodec.java
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLDataException;
+import java.sql.SQLException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Blob codec */
+public class BlobCodec implements Codec<Blob> {
+
+  /** default instance */
+  public static final BlobCodec INSTANCE = new BlobCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.BIT,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB,
+          DataType.STRING,
+          DataType.VARSTRING,
+          DataType.VARCHAR);
+
+  public String className() {
+    return Blob.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(Blob.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Blob && !(value instanceof Clob);
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Blob decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    switch (column.getType()) {
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        if (!column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format(
+                  "Data type %s (not binary) cannot be decoded as Blob", column.getType()));
+        }
+      case BIT:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+      case BLOB:
+      case GEOMETRY:
+        if (!column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format(
+                  "Data type %s (not binary) cannot be decoded as Blob", column.getType()));
+        }
+        return buf.readBlob(length);
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Blob", column.getType()));
+    }
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Blob decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    switch (column.getType()) {
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        if (!column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format(
+                  "Data type %s (not binary) cannot be decoded as Blob", column.getType()));
+        }
+      case BIT:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+      case BLOB:
+      case GEOMETRY:
+        if (!column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format(
+                  "Data type %s (not binary) cannot be decoded as Blob", column.getType()));
+        }
+        buf.skip(length);
+        return new MariaDbBlob(buf.buf(), buf.pos() - length, length);
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Blob", column.getType()));
+    }
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException, SQLException {
+    encoder.writeBytes(ByteArrayCodec.BINARY_PREFIX);
+    byte[] array = new byte[4096];
+    InputStream is = ((Blob) value).getBinaryStream();
+    int len;
+
+    if (maxLength == null) {
+      while ((len = is.read(array)) > 0) {
+        encoder.writeBytesEscaped(
+            array, len, (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+      }
+    } else {
+      long maxLen = maxLength;
+      while (maxLen > 0 && (len = is.read(array)) > 0) {
+        encoder.writeBytesEscaped(
+            array,
+            Math.min(len, (int) maxLen),
+            (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+        maxLen -= len;
+      }
+    }
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException, SQLException {
+    long length;
+    InputStream is = ((Blob) value).getBinaryStream();
+    try {
+      length = ((Blob) value).length();
+      if (maxLength != null) length = Math.min(maxLength, length);
+
+      // if not have thrown an error
+      encoder.writeLength(length);
+      byte[] array = new byte[4096];
+      int len;
+      long remainingLen = length;
+      while ((len = is.read(array)) > 0) {
+        encoder.writeBytes(array, 0, Math.min((int) remainingLen, len));
+        remainingLen -= len;
+        if (remainingLen < 0) break;
+      }
+
+    } catch (SQLException sqle) {
+      byte[] val = encode(is, maxLength);
+      encoder.writeLength(val.length);
+      encoder.writeBytes(val, 0, val.length);
+    }
+  }
+
+  @Override
+  public void encodeLongData(Writer encoder, Blob value, Long maxLength)
+      throws IOException, SQLException {
+    byte[] array = new byte[4096];
+    InputStream is = value.getBinaryStream();
+
+    if (maxLength == null) {
+      int len;
+      while ((len = is.read(array)) > 0) {
+        encoder.writeBytes(array, 0, len);
+      }
+    } else {
+      long maxLen = maxLength;
+      int len;
+      while (maxLen > 0 && (len = is.read(array)) > 0) {
+        encoder.writeBytes(array, 0, Math.min(len, (int) maxLen));
+        maxLen -= len;
+      }
+    }
+  }
+
+  @Override
+  public byte[] encodeData(Blob value, Long maxLength) throws IOException, SQLException {
+    return encode(value.getBinaryStream(), maxLength);
+  }
+
+  private byte[] encode(InputStream is, Long maxLength) throws IOException {
+    ByteArrayOutputStream bb = new ByteArrayOutputStream();
+    byte[] array = new byte[4096];
+    if (maxLength == null) {
+      int len;
+      while ((len = is.read(array)) > 0) {
+        bb.write(array, 0, len);
+      }
+    } else {
+      long maxLen = maxLength;
+      int len;
+      while (maxLen > 0 && (len = is.read(array)) > 0) {
+        bb.write(array, 0, Math.min(len, (int) maxLen));
+        maxLen -= len;
+      }
+    }
+    return bb.toByteArray();
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+
+  public boolean canEncodeLongData() {
+    return true;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/BooleanCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/BooleanCodec.java
new file mode 100644
index 0000000..5eaede1
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/BooleanCodec.java
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Boolean codec */
+public class BooleanCodec implements Codec<Boolean> {
+
+  /** default instance */
+  public static final BooleanCodec INSTANCE = new BooleanCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BIGINT,
+          DataType.INTEGER,
+          DataType.MEDIUMINT,
+          DataType.SMALLINT,
+          DataType.YEAR,
+          DataType.TINYINT,
+          DataType.DECIMAL,
+          DataType.OLDDECIMAL,
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.BIT,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Boolean.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Boolean.TYPE) || type.isAssignableFrom(Boolean.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Boolean;
+  }
+
+  public Boolean decodeText(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeBooleanText(buffer, length);
+  }
+
+  public Boolean decodeBinary(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeBooleanBinary(buffer, length);
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeAscii(((Boolean) value) ? "1" : "0");
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeByte(((Boolean) value) ? 1 : 0);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.TINYINT.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/ByteArrayCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/ByteArrayCodec.java
new file mode 100644
index 0000000..afde4b7
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/ByteArrayCodec.java
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Byte array codec. */
+public class ByteArrayCodec implements Codec<byte[]> {
+
+  /** binary prefix */
+  public static final byte[] BINARY_PREFIX = {'_', 'b', 'i', 'n', 'a', 'r', 'y', ' ', '\''};
+
+  /** default instance */
+  public static final ByteArrayCodec INSTANCE = new ByteArrayCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB,
+          DataType.BIT,
+          DataType.GEOMETRY,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING);
+
+  public String className() {
+    return "byte[]";
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Byte.TYPE && type.isArray())
+            || type.isAssignableFrom(byte[].class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof byte[];
+  }
+
+  @Override
+  public byte[] decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return getBytes(buf, length, column);
+  }
+
+  private byte[] getBytes(ReadableByteBuf buf, int length, ColumnDecoder column)
+      throws SQLDataException {
+    switch (column.getType()) {
+      case BIT:
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+      case STRING:
+      case VARSTRING:
+      case VARCHAR:
+      case GEOMETRY:
+        byte[] arr = new byte[length];
+        buf.readBytes(arr);
+        return arr;
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as byte[]", column.getType()));
+    }
+  }
+
+  @Override
+  public byte[] decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return getBytes(buf, length, column);
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    int length = ((byte[]) value).length;
+
+    encoder.writeBytes(BINARY_PREFIX);
+    encoder.writeBytesEscaped(
+        ((byte[]) value),
+        maxLength == null ? length : Math.min(length, maxLength.intValue()),
+        (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    int length = ((byte[]) value).length;
+    if (maxLength != null) length = Math.min(length, maxLength.intValue());
+    encoder.writeLength(length);
+    encoder.writeBytes(((byte[]) value), 0, length);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/ByteCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/ByteCodec.java
new file mode 100644
index 0000000..ff8eefa
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/ByteCodec.java
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Byte codec */
+public class ByteCodec implements Codec<Byte> {
+
+  /** default instance */
+  public static final ByteCodec INSTANCE = new ByteCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.BIGINT,
+          DataType.YEAR,
+          DataType.BIT,
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.OLDDECIMAL,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB,
+          DataType.DECIMAL,
+          DataType.ENUM,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.VARCHAR);
+
+  /**
+   * Parse Bits value to long value
+   *
+   * @param buf packet buffer
+   * @param length encoded length
+   * @return long value
+   */
+  public static long parseBit(ReadableByteBuf buf, int length) {
+    if (length == 1) {
+      return buf.readUnsignedByte();
+    }
+    long val = 0;
+    int idx = 0;
+    do {
+      val += ((long) buf.readUnsignedByte()) << (8 * length);
+      idx++;
+    } while (idx < length);
+    return val;
+  }
+
+  public String className() {
+    return Byte.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Byte.TYPE) || type.isAssignableFrom(Byte.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Byte;
+  }
+
+  @Override
+  public Byte decodeText(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeByteText(buffer, length);
+  }
+
+  @Override
+  public Byte decodeBinary(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeByteBinary(buffer, length);
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeAscii(Integer.toString((Byte) value));
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeByte((byte) value);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.TINYINT.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/ClobCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/ClobCodec.java
new file mode 100644
index 0000000..a7e33a8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/ClobCodec.java
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Clob codec */
+public class ClobCodec implements Codec<Clob> {
+
+  /** Default instance */
+  public static final ClobCodec INSTANCE = new ClobCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Clob.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && (type.isAssignableFrom(Clob.class) || type.isAssignableFrom(NClob.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Clob;
+  }
+
+  @Override
+  public Clob decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return getClob(buf, length, column);
+  }
+
+  @SuppressWarnings("fallthrough")
+  private Clob getClob(ReadableByteBuf buf, int length, ColumnDecoder column)
+      throws SQLDataException {
+    switch (column.getType()) {
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as Clob", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        Clob clob = new MariaDbClob(buf.buf(), buf.pos(), length);
+        buf.skip(length);
+        return clob;
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Clob", column.getType()));
+    }
+  }
+
+  @Override
+  public Clob decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return getClob(buf, length, column);
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException, SQLException {
+    Reader reader = ((Clob) value).getCharacterStream();
+    char[] buf = new char[4096];
+    int len;
+    long remainingLen = maxLength == null ? Long.MAX_VALUE : maxLength;
+    encoder.writeByte('\'');
+    while (remainingLen > 0 && (len = reader.read(buf)) >= 0) {
+      byte[] data =
+          new String(buf, 0, (int) Math.min(len, remainingLen)).getBytes(StandardCharsets.UTF_8);
+      encoder.writeBytesEscaped(
+          data, data.length, (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+      remainingLen -= len;
+    }
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException, SQLException {
+    // prefer use of encodeLongData, because length is unknown
+    Reader reader = ((Clob) value).getCharacterStream();
+    byte[] clobBytes = new byte[4096];
+    int pos = 0;
+    char[] buf = new char[4096];
+    long remainingLen = maxLength == null ? Long.MAX_VALUE : maxLength;
+    int len;
+    while (remainingLen > 0 && (len = reader.read(buf)) > 0) {
+      byte[] data =
+          new String(buf, 0, (int) Math.min(len, remainingLen)).getBytes(StandardCharsets.UTF_8);
+      if (clobBytes.length - pos < data.length) {
+        byte[] newBlobBytes = new byte[clobBytes.length + 65536];
+        System.arraycopy(clobBytes, 0, newBlobBytes, 0, pos);
+        clobBytes = newBlobBytes;
+      }
+      System.arraycopy(data, 0, clobBytes, pos, data.length);
+      pos += data.length;
+      remainingLen -= len;
+    }
+    encoder.writeLength(pos);
+    encoder.writeBytes(clobBytes, 0, pos);
+  }
+
+  @Override
+  public void encodeLongData(Writer encoder, Clob value, Long maxLength)
+      throws IOException, SQLException {
+    Reader reader = value.getCharacterStream();
+    char[] buf = new char[4096];
+    int len;
+    long remainingLen = maxLength == null ? Long.MAX_VALUE : maxLength;
+    while (remainingLen > 0 && (len = reader.read(buf)) > 0) {
+      byte[] data =
+          new String(buf, 0, (int) Math.min(len, remainingLen)).getBytes(StandardCharsets.UTF_8);
+      encoder.writeBytes(data, 0, data.length);
+      remainingLen -= len;
+    }
+  }
+
+  @Override
+  public byte[] encodeData(Clob value, Long maxLength) throws IOException, SQLException {
+    ByteArrayOutputStream bb = new ByteArrayOutputStream();
+    Reader reader = value.getCharacterStream();
+    char[] buf = new char[4096];
+    int len;
+    long remainingLen = maxLength == null ? Long.MAX_VALUE : maxLength;
+    while (remainingLen > 0 && (len = reader.read(buf)) > 0) {
+      byte[] data =
+          new String(buf, 0, (int) Math.min(len, remainingLen)).getBytes(StandardCharsets.UTF_8);
+      bb.write(data, 0, data.length);
+      remainingLen -= len;
+    }
+    return bb.toByteArray();
+  }
+
+  public boolean canEncodeLongData() {
+    return true;
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.VARSTRING.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/DateCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/DateCodec.java
new file mode 100644
index 0000000..4e83e63
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/DateCodec.java
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.Date;
+import java.sql.SQLDataException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Date codec */
+public class DateCodec implements Codec<Date> {
+
+  /** default instance */
+  public static final DateCodec INSTANCE = new DateCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.DATE,
+          DataType.NEWDATE,
+          DataType.DATETIME,
+          DataType.TIMESTAMP,
+          DataType.YEAR,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Date.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(Date.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Date || java.util.Date.class.equals(value.getClass());
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Date decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return column.decodeDateText(buf, length, cal);
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Date decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return column.decodeDateBinary(buf, length, cal);
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object val, Calendar providedCal, Long maxLen)
+      throws IOException {
+    Calendar cal = providedCal == null ? Calendar.getInstance() : providedCal;
+    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+    sdf.setTimeZone(cal.getTimeZone());
+    String dateString = sdf.format(val);
+
+    encoder.writeByte('\'');
+    encoder.writeAscii(dateString);
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar providedCal, Long maxLength)
+      throws IOException {
+    Calendar cal = providedCal == null ? Calendar.getInstance() : providedCal;
+    synchronized (cal) {
+      cal.clear();
+      cal.setTimeInMillis(((java.util.Date) value).getTime());
+      encoder.writeByte(4); // length
+      encoder.writeShort((short) cal.get(Calendar.YEAR));
+      encoder.writeByte(((cal.get(Calendar.MONTH) + 1) & 0xff));
+      encoder.writeByte((cal.get(Calendar.DAY_OF_MONTH) & 0xff));
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DATE.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/DoubleCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/DoubleCodec.java
new file mode 100644
index 0000000..47da185
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/DoubleCodec.java
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Double codec */
+public class DoubleCodec implements Codec<Double> {
+
+  /** default instance */
+  public static final DoubleCodec INSTANCE = new DoubleCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.BIGINT,
+          DataType.YEAR,
+          DataType.OLDDECIMAL,
+          DataType.DECIMAL,
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Double.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Double.TYPE) || type.isAssignableFrom(Double.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Double;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Double decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return column.decodeDoubleText(buf, length);
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Double decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return column.decodeDoubleBinary(buf, length);
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeAscii(value.toString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeDouble((Double) value);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DOUBLE.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/DurationCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/DurationCodec.java
new file mode 100644
index 0000000..d0f235f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/DurationCodec.java
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.time.Duration;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Duration codec */
+public class DurationCodec implements Codec<Duration> {
+
+  /** default instance */
+  public static final DurationCodec INSTANCE = new DurationCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TIME,
+          DataType.DATETIME,
+          DataType.TIMESTAMP,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Duration.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(Duration.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Duration;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Duration decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+
+    int[] parts;
+    switch (column.getType()) {
+      case TIMESTAMP:
+      case DATETIME:
+        parts = LocalDateTimeCodec.parseTimestamp(buf.readAscii(length));
+        if (parts == null) return null;
+        return Duration.ZERO
+            .plusDays(parts[2] - 1)
+            .plusHours(parts[3])
+            .plusMinutes(parts[4])
+            .plusSeconds(parts[5])
+            .plusNanos(parts[6]);
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as Duration", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case TIME:
+      case VARCHAR:
+      case VARSTRING:
+      case STRING:
+        parts = LocalTimeCodec.parseTime(buf, length, column);
+        Duration d =
+            Duration.ZERO
+                .plusHours(parts[1])
+                .plusMinutes(parts[2])
+                .plusSeconds(parts[3])
+                .plusNanos(parts[4]);
+        if (parts[0] == -1) return d.negated();
+        return d;
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Duration", column.getType()));
+    }
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Duration decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+
+    long days = 0;
+    int hours = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+    switch (column.getType()) {
+      case TIME:
+        boolean negate = false;
+        if (length > 0) {
+          negate = buf.readUnsignedByte() == 0x01;
+          if (length > 4) {
+            days = buf.readUnsignedInt();
+            if (length > 7) {
+              hours = buf.readByte();
+              minutes = buf.readByte();
+              seconds = buf.readByte();
+              if (length > 8) {
+                microseconds = buf.readInt();
+              }
+            }
+          }
+        }
+
+        Duration duration =
+            Duration.ZERO
+                .plusDays(days)
+                .plusHours(hours)
+                .plusMinutes(minutes)
+                .plusSeconds(seconds)
+                .plusNanos(microseconds * 1000);
+        if (negate) return duration.negated();
+        return duration;
+
+      case TIMESTAMP:
+      case DATETIME:
+        if (length == 0) return null;
+        int year = buf.readUnsignedShort();
+        int month = buf.readByte();
+        days = buf.readByte();
+        if (length > 4) {
+          hours = buf.readByte();
+          minutes = buf.readByte();
+          seconds = buf.readByte();
+
+          if (length > 7) {
+            microseconds = buf.readUnsignedInt();
+          }
+        }
+
+        // xpand workaround https://jira.mariadb.org/browse/XPT-274
+        if (year == 0 && month == 0 && days == 0 && hours == 0 && minutes == 0 && seconds == 0)
+          return null;
+
+        return Duration.ZERO
+            .plusDays(days - 1)
+            .plusHours(hours)
+            .plusMinutes(minutes)
+            .plusSeconds(seconds)
+            .plusNanos(microseconds * 1000);
+
+      case VARCHAR:
+      case VARSTRING:
+      case STRING:
+        int[] parts = LocalTimeCodec.parseTime(buf, length, column);
+        Duration d =
+            Duration.ZERO
+                .plusHours(parts[1])
+                .plusMinutes(parts[2])
+                .plusSeconds(parts[3])
+                .plusNanos(parts[4]);
+        if (parts[0] == -1) return d.negated();
+        return d;
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Duration", column.getType()));
+    }
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object val, Calendar cal, Long maxLen)
+      throws IOException {
+    long s = ((Duration) val).getSeconds();
+    long microSecond = ((Duration) val).getNano() / 1000;
+    encoder.writeByte('\'');
+    if (microSecond != 0) {
+      encoder.writeAscii(
+          String.format("%d:%02d:%02d.%06d", s / 3600, (s % 3600) / 60, (s % 60), microSecond));
+    } else {
+      encoder.writeAscii(String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60)));
+    }
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object val, Calendar cal, Long maxLength)
+      throws IOException {
+    int nano = ((Duration) val).getNano();
+    if (nano > 0) {
+      encoder.writeByte((byte) 12);
+      encodeDuration(encoder, ((Duration) val));
+      encoder.writeInt(nano / 1000);
+    } else {
+      encoder.writeByte((byte) 8);
+      encodeDuration(encoder, ((Duration) val));
+    }
+  }
+
+  private void encodeDuration(Writer encoder, Duration value) throws IOException {
+    encoder.writeByte((byte) (value.isNegative() ? 1 : 0));
+    encoder.writeInt((int) value.toDays());
+    encoder.writeByte((byte) (value.toHours() - 24 * value.toDays()));
+    encoder.writeByte((byte) (value.toMinutes() - 60 * value.toHours()));
+    encoder.writeByte((byte) (value.getSeconds() - 60 * value.toMinutes()));
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.TIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/FloatCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/FloatCodec.java
new file mode 100644
index 0000000..87256c4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/FloatCodec.java
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Float codec */
+public class FloatCodec implements Codec<Float> {
+
+  /** default instance */
+  public static final FloatCodec INSTANCE = new FloatCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.FLOAT,
+          DataType.BIGINT,
+          DataType.OLDDECIMAL,
+          DataType.DECIMAL,
+          DataType.YEAR,
+          DataType.DOUBLE,
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Float.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Float.TYPE) || type.isAssignableFrom(Float.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Float;
+  }
+
+  @Override
+  public Float decodeText(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeFloatText(buffer, length);
+  }
+
+  @Override
+  public Float decodeBinary(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeFloatBinary(buffer, length);
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeAscii(value.toString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeFloat((Float) value);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.FLOAT.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/GeometryCollectionCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/GeometryCollectionCodec.java
new file mode 100644
index 0000000..a72bdca
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/GeometryCollectionCodec.java
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.type.*;
+
+/** GeometryCollection codec */
+public class GeometryCollectionCodec implements Codec<GeometryCollection> {
+
+  /** default instance */
+  public static final GeometryCollectionCodec INSTANCE = new GeometryCollectionCodec();
+
+  public String className() {
+    return GeometryCollection.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.GEOMETRY && type.isAssignableFrom(GeometryCollection.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof GeometryCollection;
+  }
+
+  @Override
+  public GeometryCollection decodeText(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    return decodeBinary(buf, length, column, cal);
+  }
+
+  @Override
+  public GeometryCollection decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    if (column.getType() == DataType.GEOMETRY) {
+      buf.skip(4); // SRID
+      Geometry geo = Geometry.getGeometry(buf, length - 4, column);
+      if (geo instanceof GeometryCollection) return (GeometryCollection) geo;
+      throw new SQLDataException(
+          String.format(
+              "Geometric type %s cannot be decoded as GeometryCollection",
+              geo.getClass().getName()));
+    }
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as GeometryCollection", column.getType()));
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeBytes(("ST_GeomCollFromText('" + value.toString() + "')").getBytes());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    GeometryCollection geometryCollection = (GeometryCollection) value;
+
+    int length = 13;
+    for (Geometry geo : geometryCollection.getGeometries()) {
+      if (geo instanceof Point) {
+        length += 21;
+      } else if (geo instanceof LineString) {
+        length += 9 + ((LineString) geo).getPoints().length * 16;
+      } else if (geo instanceof Polygon) {
+        length += 9;
+        for (LineString ls : ((Polygon) geo).getLines()) {
+          length += 4 + ls.getPoints().length * 16;
+        }
+      } else if (geo instanceof MultiPoint) {
+        length += 9 + ((MultiPoint) geo).getPoints().length * 21;
+      } else if (geo instanceof MultiLineString) {
+        length += 9;
+        for (LineString ls : ((MultiLineString) geo).getLines()) {
+          length += 9 + ls.getPoints().length * 16;
+        }
+      } else if (geo instanceof MultiPolygon) {
+        length += 9;
+        for (Polygon poly : ((MultiPolygon) geo).getPolygons()) {
+          length += 9;
+          for (LineString ls : poly.getLines()) {
+            length += 4 + ls.getPoints().length * 16;
+          }
+        }
+      }
+    }
+
+    encoder.writeLength(length);
+    encoder.writeInt(0); // SRID
+    encoder.writeByte(0x01); // LITTLE ENDIAN
+    encoder.writeInt(7); // wkbGeometryCollection
+    encoder.writeInt(geometryCollection.getGeometries().length);
+    for (Geometry geo : geometryCollection.getGeometries()) {
+      if (geo instanceof Point) {
+        Point pt = (Point) geo;
+        encoder.writeByte(0x01); // LITTLE ENDIAN
+        encoder.writeInt(1); // wkbPoint
+        encoder.writeDouble(pt.getX());
+        encoder.writeDouble(pt.getY());
+      } else if (geo instanceof LineString) {
+        LineString ls = (LineString) geo;
+        encoder.writeByte(0x01); // LITTLE ENDIAN
+        encoder.writeInt(2); // wkbLineString
+        encoder.writeInt(ls.getPoints().length);
+        for (Point pt : ls.getPoints()) {
+          encoder.writeDouble(pt.getX());
+          encoder.writeDouble(pt.getY());
+        }
+      } else if (geo instanceof Polygon) {
+        Polygon poly = (Polygon) geo;
+        encoder.writeByte(0x01); // LITTLE ENDIAN
+        encoder.writeInt(3); // wkbPolygon
+        encoder.writeInt(poly.getLines().length);
+        for (LineString ls : poly.getLines()) {
+          encoder.writeInt(ls.getPoints().length);
+          for (Point pt : ls.getPoints()) {
+            encoder.writeDouble(pt.getX());
+            encoder.writeDouble(pt.getY());
+          }
+        }
+      } else if (geo instanceof MultiPoint) {
+        MultiPoint mp = (MultiPoint) geo;
+        encoder.writeByte(0x01); // LITTLE ENDIAN
+        encoder.writeInt(4); // wkbMultiPoint
+        encoder.writeInt(mp.getPoints().length);
+        for (Point pt : mp.getPoints()) {
+          encoder.writeByte(0x01); // LITTLE ENDIAN
+          encoder.writeInt(1); // wkbPoint
+          encoder.writeDouble(pt.getX());
+          encoder.writeDouble(pt.getY());
+        }
+      } else if (geo instanceof MultiLineString) {
+        MultiLineString mlines = (MultiLineString) geo;
+        encoder.writeByte(0x01); // LITTLE ENDIAN
+        encoder.writeInt(5); // wkbMultiLineString
+        encoder.writeInt(mlines.getLines().length);
+        for (LineString ls : mlines.getLines()) {
+          encoder.writeByte(0x01); // LITTLE ENDIAN
+          encoder.writeInt(2); // wkbLineString
+          encoder.writeInt(ls.getPoints().length); // nb points
+          for (Point pt : ls.getPoints()) {
+            encoder.writeDouble(pt.getX());
+            encoder.writeDouble(pt.getY());
+          }
+        }
+      } else if (geo instanceof MultiPolygon) {
+        MultiPolygon multiPolygon = (MultiPolygon) geo;
+        encoder.writeByte(0x01); // LITTLE ENDIAN
+        encoder.writeInt(6); // wkbMultiPolygon
+        encoder.writeInt(multiPolygon.getPolygons().length); // nb polygon
+
+        for (Polygon poly : multiPolygon.getPolygons()) {
+          encoder.writeByte(0x01); // LITTLE ENDIAN
+          encoder.writeInt(3); // wkbPolygon
+          encoder.writeInt(poly.getLines().length);
+          for (LineString ls : poly.getLines()) {
+            encoder.writeInt(ls.getPoints().length);
+            for (Point pt : ls.getPoints()) {
+              encoder.writeDouble(pt.getX());
+              encoder.writeDouble(pt.getY());
+            }
+          }
+        }
+      }
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/InstantCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/InstantCodec.java
new file mode 100644
index 0000000..ee6f344
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/InstantCodec.java
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.time.*;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Instant codec */
+public class InstantCodec implements Codec<Instant> {
+
+  /** default instance */
+  public static final InstantCodec INSTANCE = new InstantCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.DATETIME,
+          DataType.DATE,
+          DataType.YEAR,
+          DataType.TIMESTAMP,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.TIME,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Instant.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(Instant.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Instant;
+  }
+
+  @Override
+  public Instant decodeText(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar calParam)
+      throws SQLDataException {
+    LocalDateTime localDateTime =
+        LocalDateTimeCodec.INSTANCE.decodeText(buf, length, column, calParam);
+    if (localDateTime == null) return null;
+    return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
+  }
+
+  @Override
+  public Instant decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar calParam)
+      throws SQLDataException {
+    LocalDateTime localDateTime =
+        LocalDateTimeCodec.INSTANCE.decodeBinary(buf, length, column, calParam);
+    if (localDateTime == null) return null;
+    return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object val, Calendar calParam, Long maxLen)
+      throws IOException {
+    Instant instant = (Instant) val;
+
+    encoder.writeByte('\'');
+    ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
+    if (calParam != null) {
+      zonedDateTime = zonedDateTime.withZoneSameInstant(calParam.getTimeZone().toZoneId());
+    }
+    encoder.writeAscii(
+        zonedDateTime.format(
+            instant.getNano() != 0
+                ? LocalDateTimeCodec.TIMESTAMP_FORMAT
+                : LocalDateTimeCodec.TIMESTAMP_FORMAT_NO_FRACTIONAL));
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar calParam, Long maxLength)
+      throws IOException {
+    Instant instant = (Instant) value;
+    ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
+    if (calParam != null) {
+      zonedDateTime = zonedDateTime.withZoneSameInstant(calParam.getTimeZone().toZoneId());
+    }
+
+    int nano = zonedDateTime.getNano();
+    if (nano > 0) {
+      encoder.writeByte((byte) 11);
+      encoder.writeShort((short) zonedDateTime.get(ChronoField.YEAR));
+      encoder.writeByte(zonedDateTime.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(zonedDateTime.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(zonedDateTime.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(zonedDateTime.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(zonedDateTime.get(ChronoField.SECOND_OF_MINUTE));
+      encoder.writeInt(nano / 1000);
+    } else {
+      encoder.writeByte((byte) 7);
+      encoder.writeShort((short) zonedDateTime.get(ChronoField.YEAR));
+      encoder.writeByte(zonedDateTime.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(zonedDateTime.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(zonedDateTime.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(zonedDateTime.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(zonedDateTime.get(ChronoField.SECOND_OF_MINUTE));
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DATETIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/IntCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/IntCodec.java
new file mode 100644
index 0000000..f1d9e16
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/IntCodec.java
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Integer codec */
+public class IntCodec implements Codec<Integer> {
+
+  /** default instance */
+  public static final IntCodec INSTANCE = new IntCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.OLDDECIMAL,
+          DataType.VARCHAR,
+          DataType.DECIMAL,
+          DataType.ENUM,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.BIGINT,
+          DataType.BIT,
+          DataType.YEAR,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Integer.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Integer.TYPE) || type.isAssignableFrom(Integer.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Integer;
+  }
+
+  @Override
+  public Integer decodeText(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeIntText(buffer, length);
+  }
+
+  @Override
+  public Integer decodeBinary(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeIntBinary(buffer, length);
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeAscii(value.toString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeInt((Integer) value);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.INTEGER.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/LineStringCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/LineStringCodec.java
new file mode 100644
index 0000000..8ca68f4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/LineStringCodec.java
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.type.*;
+
+/** LineString codec */
+public class LineStringCodec implements Codec<LineString> {
+
+  /** default instance */
+  public static final LineStringCodec INSTANCE = new LineStringCodec();
+
+  public String className() {
+    return LineString.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.GEOMETRY && type.isAssignableFrom(LineString.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof LineString;
+  }
+
+  @Override
+  public LineString decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return decodeBinary(buf, length, column, cal);
+  }
+
+  @Override
+  public LineString decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    if (column.getType() == DataType.GEOMETRY) {
+      buf.skip(4); // SRID
+      Geometry geo = Geometry.getGeometry(buf, length - 4, column);
+      if (geo instanceof LineString) return (LineString) geo;
+      throw new SQLDataException(
+          String.format(
+              "Geometric type %s cannot be decoded as LineString", geo.getClass().getName()));
+    }
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as LineString", column.getType()));
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeBytes(("ST_LineFromText('" + value.toString() + "')").getBytes());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    LineString line = (LineString) value;
+
+    encoder.writeLength(13 + line.getPoints().length * 16L);
+    encoder.writeInt(0); // SRID
+    encoder.writeByte(0x01); // LITTLE ENDIAN
+    encoder.writeInt(2); // wkbLineString
+    encoder.writeInt(line.getPoints().length);
+    for (Point pt : line.getPoints()) {
+      encoder.writeDouble(pt.getX());
+      encoder.writeDouble(pt.getY());
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/LocalDateCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/LocalDateCodec.java
new file mode 100644
index 0000000..0bb65bf
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/LocalDateCodec.java
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** LocalDate codec */
+public class LocalDateCodec implements Codec<LocalDate> {
+
+  /** default instance */
+  public static final LocalDateCodec INSTANCE = new LocalDateCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.DATE,
+          DataType.NEWDATE,
+          DataType.DATETIME,
+          DataType.TIMESTAMP,
+          DataType.YEAR,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  /**
+   * Parse text encoded Date
+   *
+   * @param buf packet buffer
+   * @param length data length
+   * @return date/month/year array
+   */
+  public static int[] parseDate(ReadableByteBuf buf, int length) {
+    int[] datePart = new int[] {0, 0, 0};
+    int partIdx = 0;
+    int idx = 0;
+
+    while (idx++ < length) {
+      byte b = buf.readByte();
+      if (b == '-') {
+        partIdx++;
+        continue;
+      }
+      datePart[partIdx] = datePart[partIdx] * 10 + b - 48;
+    }
+
+    if (datePart[0] == 0 && datePart[1] == 0 && datePart[2] == 0) {
+      return null;
+    }
+    return datePart;
+  }
+
+  public String className() {
+    return LocalDate.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(LocalDate.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof LocalDate;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public LocalDate decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+
+    int[] parts;
+    switch (column.getType()) {
+      case YEAR:
+        short y = (short) buf.atoull(length);
+
+        if (length == 2 && column.getColumnLength() == 2) {
+          // YEAR(2) - deprecated
+          if (y <= 69) {
+            y += 2000;
+          } else {
+            y += 1900;
+          }
+        }
+
+        return LocalDate.of(y, 1, 1);
+      case NEWDATE:
+      case DATE:
+        parts = parseDate(buf, length);
+        break;
+
+      case TIMESTAMP:
+      case DATETIME:
+        parts = LocalDateTimeCodec.parseTimestamp(buf.readAscii(length));
+        break;
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as Date", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case VARSTRING:
+      case VARCHAR:
+      case STRING:
+        String val = buf.readString(length);
+        String[] stDatePart = val.split("[- ]");
+        if (stDatePart.length < 3) {
+          throw new SQLDataException(
+              String.format("value '%s' (%s) cannot be decoded as Date", val, column.getType()));
+        }
+
+        try {
+          int year = Integer.parseInt(stDatePart[0]);
+          int month = Integer.parseInt(stDatePart[1]);
+          int dayOfMonth = Integer.parseInt(stDatePart[2]);
+          if (year == 0 && month == 0 && dayOfMonth == 0) return null;
+          return LocalDate.of(year, month, dayOfMonth);
+        } catch (NumberFormatException nfe) {
+          throw new SQLDataException(
+              String.format("value '%s' (%s) cannot be decoded as Date", val, column.getType()));
+        }
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Date", column.getType()));
+    }
+    if (parts == null) return null;
+    return LocalDate.of(parts[0], parts[1], parts[2]);
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public LocalDate decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+
+    int year;
+    int month = 1;
+    int dayOfMonth = 1;
+
+    switch (column.getType()) {
+      case TIMESTAMP:
+      case DATETIME:
+        if (length == 0) return null;
+        year = buf.readUnsignedShort();
+        month = buf.readByte();
+        dayOfMonth = buf.readByte();
+
+        if (length > 4) {
+          buf.skip(length - 4);
+        }
+
+        // xpand workaround https://jira.mariadb.org/browse/XPT-274
+        if (year == 0 && month == 0 && dayOfMonth == 0) return null;
+        return LocalDate.of(year, month, dayOfMonth);
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as Date", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        String val = buf.readString(length);
+        String[] stDatePart = val.split("[- ]");
+        if (stDatePart.length < 3) {
+          throw new SQLDataException(
+              String.format("value '%s' (%s) cannot be decoded as Date", val, column.getType()));
+        }
+
+        try {
+          year = Integer.parseInt(stDatePart[0]);
+          month = Integer.parseInt(stDatePart[1]);
+          dayOfMonth = Integer.parseInt(stDatePart[2]);
+          if (year == 0 && month == 0 && dayOfMonth == 0) return null;
+          return LocalDate.of(year, month, dayOfMonth);
+        } catch (NumberFormatException nfe) {
+          throw new SQLDataException(
+              String.format("value '%s' (%s) cannot be decoded as Date", val, column.getType()));
+        }
+
+      case DATE:
+      case YEAR:
+        if (length == 0) return null;
+        year = buf.readUnsignedShort();
+
+        if (column.getColumnLength() == 2) {
+          // YEAR(2) - deprecated
+          if (year <= 69) {
+            year += 2000;
+          } else {
+            year += 1900;
+          }
+        }
+
+        if (length >= 4) {
+          month = buf.readByte();
+          dayOfMonth = buf.readByte();
+        }
+
+        // xpand workaround https://jira.mariadb.org/browse/XPT-274
+        if (year == 0 && month == 0 && dayOfMonth == 0) return null;
+
+        return LocalDate.of(year, month, dayOfMonth);
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Date", column.getType()));
+    }
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object val, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeByte('\'');
+    encoder.writeAscii(((LocalDate) val).format(DateTimeFormatter.ISO_LOCAL_DATE));
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar providedCal, Long maxLength)
+      throws IOException {
+    LocalDate val = (LocalDate) value;
+    encoder.writeByte(7); // length
+    encoder.writeShort((short) val.get(ChronoField.YEAR));
+    encoder.writeByte(val.get(ChronoField.MONTH_OF_YEAR));
+    encoder.writeByte(val.get(ChronoField.DAY_OF_MONTH));
+    encoder.writeBytes(new byte[] {0, 0, 0});
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DATE.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/LocalDateTimeCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/LocalDateTimeCodec.java
new file mode 100644
index 0000000..ad559ac
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/LocalDateTimeCodec.java
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.time.DateTimeException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** LocalDateTime codec */
+public class LocalDateTimeCodec implements Codec<LocalDateTime> {
+
+  /** default instance */
+  public static final LocalDateTimeCodec INSTANCE = new LocalDateTimeCodec();
+
+  /** timestamp with fractional part formatter */
+  public static final DateTimeFormatter TIMESTAMP_FORMAT =
+      DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
+
+  /** timestamp without fractional part formatter */
+  public static final DateTimeFormatter TIMESTAMP_FORMAT_NO_FRACTIONAL =
+      DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+  /** formatter */
+  public static final DateTimeFormatter MARIADB_LOCAL_DATE_TIME;
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.DATETIME,
+          DataType.TIMESTAMP,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.TIME,
+          DataType.YEAR,
+          DataType.DATE,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  static {
+    MARIADB_LOCAL_DATE_TIME =
+        new DateTimeFormatterBuilder()
+            .parseCaseInsensitive()
+            .append(DateTimeFormatter.ISO_LOCAL_DATE)
+            .appendLiteral(' ')
+            .append(DateTimeFormatter.ISO_LOCAL_TIME)
+            .toFormatter();
+  }
+
+  /**
+   * Parse timestamp to date/month/year int array
+   *
+   * @param raw string data
+   * @return date/month/year int array
+   * @throws DateTimeException if wrong format
+   */
+  public static int[] parseTimestamp(String raw) throws DateTimeException {
+    int nanoLen = -1;
+    int[] timestampsPart = new int[] {0, 0, 0, 0, 0, 0, 0};
+    int partIdx = 0;
+    for (int idx = 0; idx < raw.length(); idx++) {
+      char b = raw.charAt(idx);
+      if (b == '-' || b == ' ' || b == ':') {
+        partIdx++;
+        continue;
+      }
+      if (b == '.') {
+        partIdx++;
+        nanoLen = 0;
+        continue;
+      }
+      if (nanoLen >= 0) nanoLen++;
+      timestampsPart[partIdx] = timestampsPart[partIdx] * 10 + b - 48;
+    }
+    if (partIdx < 2) throw new DateTimeException("Wrong timestamp format");
+    if (timestampsPart[0] == 0 && timestampsPart[1] == 0 && timestampsPart[2] == 0) {
+      if (timestampsPart[3] == 0
+          && timestampsPart[4] == 0
+          && timestampsPart[5] == 0
+          && timestampsPart[6] == 0) return null;
+      timestampsPart[1] = 1;
+      timestampsPart[2] = 1;
+    }
+
+    // fix non-leading tray for nanoseconds
+    if (nanoLen >= 0) {
+      for (int begin = 0; begin < 6 - nanoLen; begin++) {
+        timestampsPart[6] = timestampsPart[6] * 10;
+      }
+      timestampsPart[6] = timestampsPart[6] * 1000;
+    }
+    return timestampsPart;
+  }
+
+  public String className() {
+    return LocalDateTime.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && type.isAssignableFrom(LocalDateTime.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof LocalDateTime;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public LocalDateTime decodeText(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    int[] parts;
+    switch (column.getType()) {
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as LocalDateTime", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        String val = buf.readString(length);
+        try {
+          parts = parseTimestamp(val);
+          if (parts == null) return null;
+          return LocalDateTime.of(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5])
+              .plusNanos(parts[6]);
+        } catch (DateTimeException dte) {
+          throw new SQLDataException(
+              String.format(
+                  "value '%s' (%s) cannot be decoded as LocalDateTime", val, column.getType()));
+        }
+
+      case DATE:
+        parts = LocalDateCodec.parseDate(buf, length);
+        if (parts == null) return null;
+        return LocalDateTime.of(parts[0], parts[1], parts[2], 0, 0, 0);
+
+      case DATETIME:
+      case TIMESTAMP:
+        parts = parseTimestamp(buf.readAscii(length));
+        if (parts == null) return null;
+        return LocalDateTime.of(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5])
+            .plusNanos(parts[6]);
+
+      case TIME:
+        parts = LocalTimeCodec.parseTime(buf, length, column);
+        if (parts[0] == -1) {
+          return LocalDateTime.of(1970, 1, 1, 0, 0)
+              .minusHours(parts[1] % 24)
+              .minusMinutes(parts[2])
+              .minusSeconds(parts[3])
+              .minusNanos(parts[4]);
+        }
+        return LocalDateTime.of(1970, 1, 1, parts[1] % 24, parts[2], parts[3]).plusNanos(parts[4]);
+
+      case YEAR:
+        int year = Integer.parseInt(buf.readAscii(length));
+        if (column.getColumnLength() <= 2) year += year >= 70 ? 1900 : 2000;
+        return LocalDateTime.of(year, 1, 1, 0, 0);
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as LocalDateTime", column.getType()));
+    }
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public LocalDateTime decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    int year = 1970;
+    int month = 1;
+    long dayOfMonth = 1;
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+
+    switch (column.getType()) {
+      case TIME:
+        // specific case for TIME, to handle value not in 00:00:00-23:59:59
+        boolean negate = buf.readByte() == 1;
+        int day = buf.readInt();
+        hour = buf.readByte();
+        minutes = buf.readByte();
+        seconds = buf.readByte();
+        if (length > 8) {
+          microseconds = buf.readUnsignedInt();
+        }
+
+        if (negate) {
+          return LocalDateTime.of(1970, 1, 1, 0, 0)
+              .minusDays(day)
+              .minusHours(hour)
+              .minusMinutes(minutes)
+              .minusSeconds(seconds)
+              .minusNanos(microseconds * 1000);
+        }
+        break;
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as LocalDateTime", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        String val = buf.readString(length);
+        try {
+          int[] parts = parseTimestamp(val);
+          if (parts == null) return null;
+          return LocalDateTime.of(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5])
+              .plusNanos(parts[6]);
+        } catch (DateTimeException dte) {
+          throw new SQLDataException(
+              String.format(
+                  "value '%s' (%s) cannot be decoded as LocalDateTime", val, column.getType()));
+        }
+
+      case DATE:
+      case TIMESTAMP:
+      case DATETIME:
+        if (length == 0) return null;
+        year = buf.readUnsignedShort();
+        month = buf.readByte();
+        dayOfMonth = buf.readByte();
+
+        if (length > 4) {
+          hour = buf.readByte();
+          minutes = buf.readByte();
+          seconds = buf.readByte();
+
+          if (length > 7) {
+            microseconds = buf.readUnsignedInt();
+          }
+        }
+
+        // xpand workaround https://jira.mariadb.org/browse/XPT-274
+        if (year == 0 && month == 0 && dayOfMonth == 0 && hour == 0 && minutes == 0 && seconds == 0)
+          return null;
+
+        break;
+
+      case YEAR:
+        year = buf.readUnsignedShort();
+        if (column.getColumnLength() <= 2) year += year >= 70 ? 1900 : 2000;
+        break;
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as LocalDateTime", column.getType()));
+    }
+
+    return LocalDateTime.of(year, month, (int) dayOfMonth, hour, minutes, seconds)
+        .plusNanos(microseconds * 1000);
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    LocalDateTime val = (LocalDateTime) value;
+    encoder.writeByte('\'');
+    encoder.writeAscii(
+        val.format(val.getNano() != 0 ? TIMESTAMP_FORMAT : TIMESTAMP_FORMAT_NO_FRACTIONAL));
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    LocalDateTime val = (LocalDateTime) value;
+    int nano = val.getNano();
+    if (nano > 0) {
+      encoder.writeByte((byte) 11);
+      encoder.writeShort((short) val.get(ChronoField.YEAR));
+      encoder.writeByte(val.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(val.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(val.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(val.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(val.get(ChronoField.SECOND_OF_MINUTE));
+      encoder.writeInt(nano / 1000);
+    } else {
+      encoder.writeByte((byte) 7);
+      encoder.writeShort((short) val.get(ChronoField.YEAR));
+      encoder.writeByte(val.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(val.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(val.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(val.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(val.get(ChronoField.SECOND_OF_MINUTE));
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DATETIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/LocalTimeCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/LocalTimeCodec.java
new file mode 100644
index 0000000..6d48e76
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/LocalTimeCodec.java
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.EnumSet;
+import java.util.TimeZone;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** LocalTime codec */
+public class LocalTimeCodec implements Codec<LocalTime> {
+
+  /** default instance */
+  public static final LocalTimeCodec INSTANCE = new LocalTimeCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TIME,
+          DataType.DATETIME,
+          DataType.TIMESTAMP,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  /**
+   * Parse text value into hour/minutes/seconds/microseconds array
+   *
+   * @param buf packet buffer
+   * @param length data length
+   * @param column column metadata
+   * @return hour/minutes/seconds/microseconds array
+   * @throws SQLDataException if parsing error occurs
+   */
+  public static int[] parseTime(ReadableByteBuf buf, int length, ColumnDecoder column)
+      throws SQLDataException {
+    int initialPos = buf.pos();
+    int[] parts = new int[5];
+    parts[0] = 1;
+    int idx = 1;
+    int partLength = 0;
+    byte b;
+    int i = 0;
+    if (length > 0 && buf.getByte() == '-') {
+      buf.skip();
+      i++;
+      parts[0] = -1;
+    }
+
+    for (; i < length; i++) {
+      b = buf.readByte();
+      if (b == ':' || b == '.') {
+        idx++;
+        partLength = 0;
+        continue;
+      }
+      if (b < '0' || b > '9') {
+        buf.pos(initialPos);
+        String val = buf.readString(length);
+        throw new SQLDataException(
+            String.format("%s value '%s' cannot be decoded as Time", column.getType(), val));
+      }
+      partLength++;
+      parts[idx] = parts[idx] * 10 + (b - '0');
+    }
+
+    if (idx < 2) {
+      buf.pos(initialPos);
+      String val = buf.readString(length);
+      throw new SQLDataException(
+          String.format("%s value '%s' cannot be decoded as Time", column.getType(), val));
+    }
+
+    // set nano real value
+    if (idx == 4) {
+      for (i = 0; i < 9 - partLength; i++) {
+        parts[4] = parts[4] * 10;
+      }
+    }
+    return parts;
+  }
+
+  public String className() {
+    return LocalTime.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(LocalTime.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof LocalTime;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public LocalTime decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+
+    int[] parts;
+    switch (column.getType()) {
+      case TIMESTAMP:
+      case DATETIME:
+        parts = LocalDateTimeCodec.parseTimestamp(buf.readString(length));
+        if (parts == null) return null;
+        return LocalTime.of(parts[3], parts[4], parts[5], parts[6]);
+
+      case TIME:
+        parts = parseTime(buf, length, column);
+        parts[1] = parts[1] % 24;
+        if (parts[0] == -1) {
+          // negative
+          long seconds = (24 * 60 * 60 - (parts[1] * 3600 + parts[2] * 60L + parts[3]));
+          return LocalTime.ofNanoOfDay(seconds * 1_000_000_000 - parts[4]);
+        }
+        return LocalTime.of(parts[1] % 24, parts[2], parts[3], parts[4]);
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as LocalTime", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case VARSTRING:
+      case VARCHAR:
+      case STRING:
+        String val = buf.readString(length);
+        try {
+          if (val.contains(" ")) {
+            ZoneId tz =
+                cal != null ? cal.getTimeZone().toZoneId() : TimeZone.getDefault().toZoneId();
+            return LocalDateTime.parse(val, LocalDateTimeCodec.MARIADB_LOCAL_DATE_TIME.withZone(tz))
+                .toLocalTime();
+          } else {
+            return LocalTime.parse(val);
+          }
+        } catch (DateTimeParseException e) {
+          throw new SQLDataException(
+              String.format(
+                  "value '%s' (%s) cannot be decoded as LocalTime", val, column.getType()));
+        }
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as LocalTime", column.getType()));
+    }
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public LocalTime decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+
+    int hour = 0;
+    int minutes = 0;
+    int seconds = 0;
+    long microseconds = 0;
+    switch (column.getType()) {
+      case TIMESTAMP:
+      case DATETIME:
+        if (length == 0) return null;
+
+        int year = buf.readUnsignedShort();
+        int month = buf.readByte();
+        int dayOfMonth = buf.readByte();
+
+        if (length > 4) {
+          hour = buf.readByte();
+          minutes = buf.readByte();
+          seconds = buf.readByte();
+
+          if (length > 7) {
+            microseconds = buf.readInt();
+          }
+        }
+
+        // xpand workaround https://jira.mariadb.org/browse/XPT-274
+        if (year == 0 && month == 0 && dayOfMonth == 0 && hour == 0 && minutes == 0 && seconds == 0)
+          return null;
+
+        return LocalTime.of(hour, minutes, seconds).plusNanos(microseconds * 1000);
+
+      case TIME:
+        boolean negate = buf.readByte() == 1;
+        if (length > 4) {
+          buf.skip(4); // skip days
+          if (length > 7) {
+            hour = buf.readByte();
+            minutes = buf.readByte();
+            seconds = buf.readByte();
+            if (length > 8) {
+              microseconds = buf.readInt();
+            }
+          }
+        }
+        if (negate) {
+          // negative
+          long nanos = (24 * 60 * 60 - (hour * 3600 + minutes * 60 + seconds));
+          return LocalTime.ofNanoOfDay(nanos * 1_000_000_000 - microseconds * 1000);
+        }
+        return LocalTime.of(hour % 24, minutes, seconds, (int) microseconds * 1000);
+
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as LocalTime", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case VARSTRING:
+      case VARCHAR:
+      case STRING:
+        String val = buf.readString(length);
+        try {
+          if (val.contains(" ")) {
+            ZoneId tz =
+                cal != null ? cal.getTimeZone().toZoneId() : TimeZone.getDefault().toZoneId();
+            return LocalDateTime.parse(val, LocalDateTimeCodec.MARIADB_LOCAL_DATE_TIME.withZone(tz))
+                .toLocalTime();
+          } else {
+            return LocalTime.parse(val);
+          }
+        } catch (DateTimeParseException e) {
+          throw new SQLDataException(
+              String.format(
+                  "value '%s' (%s) cannot be decoded as LocalTime", val, column.getType()));
+        }
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as LocalTime", column.getType()));
+    }
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    LocalTime val = (LocalTime) value;
+    StringBuilder dateString = new StringBuilder(15);
+    dateString
+        .append(val.getHour() < 10 ? "0" : "")
+        .append(val.getHour())
+        .append(val.getMinute() < 10 ? ":0" : ":")
+        .append(val.getMinute())
+        .append(val.getSecond() < 10 ? ":0" : ":")
+        .append(val.getSecond());
+
+    int microseconds = val.getNano() / 1000;
+    if (microseconds > 0) {
+      dateString.append(".");
+      if (microseconds % 1000 == 0) {
+        dateString.append(Integer.toString(microseconds / 1000 + 1000).substring(1));
+      } else {
+        dateString.append(Integer.toString(microseconds + 1000000).substring(1));
+      }
+    }
+
+    encoder.writeByte('\'');
+    encoder.writeAscii(dateString.toString());
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    LocalTime val = (LocalTime) value;
+    int nano = val.getNano();
+    if (nano > 0) {
+      encoder.writeByte((byte) 12);
+      encoder.writeByte((byte) 0);
+      encoder.writeInt(0);
+      encoder.writeByte((byte) val.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte((byte) val.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte((byte) val.get(ChronoField.SECOND_OF_MINUTE));
+      encoder.writeInt(nano / 1000);
+    } else {
+      encoder.writeByte((byte) 8);
+      encoder.writeByte((byte) 0);
+      encoder.writeInt(0);
+      encoder.writeByte((byte) val.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte((byte) val.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte((byte) val.get(ChronoField.SECOND_OF_MINUTE));
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.TIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/LongCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/LongCodec.java
new file mode 100644
index 0000000..22f05d4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/LongCodec.java
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** LongCodec codec */
+public class LongCodec implements Codec<Long> {
+
+  /** default instance */
+  public static final LongCodec INSTANCE = new LongCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.OLDDECIMAL,
+          DataType.VARCHAR,
+          DataType.DECIMAL,
+          DataType.ENUM,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.BIGINT,
+          DataType.BIT,
+          DataType.YEAR,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Long.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Integer.TYPE) || type.isAssignableFrom(Long.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Long;
+  }
+
+  @Override
+  public Long decodeText(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeLongText(buffer, length);
+  }
+
+  @Override
+  public Long decodeBinary(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeLongBinary(buffer, length);
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeAscii(value.toString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeLong((Long) value);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BIGINT.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/MultiLinestringCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/MultiLinestringCodec.java
new file mode 100644
index 0000000..8c1867f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/MultiLinestringCodec.java
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.type.Geometry;
+import org.mariadb.jdbc.type.LineString;
+import org.mariadb.jdbc.type.MultiLineString;
+import org.mariadb.jdbc.type.Point;
+
+/** MultiLineString codec */
+public class MultiLinestringCodec implements Codec<MultiLineString> {
+
+  /** default instance */
+  public static final MultiLinestringCodec INSTANCE = new MultiLinestringCodec();
+
+  public String className() {
+    return MultiLineString.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.GEOMETRY && type.isAssignableFrom(MultiLineString.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof MultiLineString;
+  }
+
+  @Override
+  public MultiLineString decodeText(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    return decodeBinary(buf, length, column, cal);
+  }
+
+  @Override
+  public MultiLineString decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    if (column.getType() == DataType.GEOMETRY) {
+      buf.skip(4); // SRID
+      Geometry geo = Geometry.getGeometry(buf, length - 4, column);
+      if (geo instanceof MultiLineString) return (MultiLineString) geo;
+      throw new SQLDataException(
+          String.format(
+              "Geometric type %s cannot be decoded as MultiLineString", geo.getClass().getName()));
+    }
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as MultiLineString", column.getType()));
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeBytes(("ST_MLineFromText('" + value.toString() + "')").getBytes());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    MultiLineString mp = (MultiLineString) value;
+
+    int length = 13;
+    for (LineString ls : mp.getLines()) {
+      length += 9 + ls.getPoints().length * 16;
+    }
+
+    encoder.writeLength(length);
+    encoder.writeInt(0); // SRID
+    encoder.writeByte(0x01); // LITTLE ENDIAN
+    encoder.writeInt(5); // wkbMultiLineString
+    encoder.writeInt(mp.getLines().length);
+    for (LineString ls : mp.getLines()) {
+      encoder.writeByte(0x01); // LITTLE ENDIAN
+      encoder.writeInt(2); // wkbLineString
+      encoder.writeInt(ls.getPoints().length); // nb points
+      for (Point pt : ls.getPoints()) {
+        encoder.writeDouble(pt.getX());
+        encoder.writeDouble(pt.getY());
+      }
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/MultiPointCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/MultiPointCodec.java
new file mode 100644
index 0000000..f18de3b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/MultiPointCodec.java
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.type.Geometry;
+import org.mariadb.jdbc.type.MultiPoint;
+import org.mariadb.jdbc.type.Point;
+
+/** MultiPoint codec */
+public class MultiPointCodec implements Codec<MultiPoint> {
+
+  /** default instance */
+  public static final MultiPointCodec INSTANCE = new MultiPointCodec();
+
+  public String className() {
+    return MultiPoint.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.GEOMETRY && type.isAssignableFrom(MultiPoint.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof MultiPoint;
+  }
+
+  @Override
+  public MultiPoint decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return decodeBinary(buf, length, column, cal);
+  }
+
+  @Override
+  public MultiPoint decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    if (column.getType() == DataType.GEOMETRY) {
+      buf.skip(4); // SRID
+      Geometry geo = Geometry.getGeometry(buf, length - 4, column);
+      if (geo instanceof MultiPoint) return (MultiPoint) geo;
+      throw new SQLDataException(
+          String.format(
+              "Geometric type %s cannot be decoded as MultiPoint", geo.getClass().getName()));
+    }
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as MultiPoint", column.getType()));
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeBytes(("ST_MPointFromText('" + value.toString() + "')").getBytes());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    MultiPoint mp = (MultiPoint) value;
+    encoder.writeLength(13 + mp.getPoints().length * 21L);
+    encoder.writeInt(0); // SRID
+    encoder.writeByte(0x01); // LITTLE ENDIAN
+    encoder.writeInt(4); // wkbMultiPoint
+    encoder.writeInt(mp.getPoints().length);
+    for (Point pt : mp.getPoints()) {
+      encoder.writeByte(0x01); // LITTLE ENDIAN
+      encoder.writeInt(1); // wkbPoint
+      encoder.writeDouble(pt.getX());
+      encoder.writeDouble(pt.getY());
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/MultiPolygonCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/MultiPolygonCodec.java
new file mode 100644
index 0000000..2f74c52
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/MultiPolygonCodec.java
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.type.*;
+
+/** MultiPolygon codec */
+public class MultiPolygonCodec implements Codec<MultiPolygon> {
+
+  /** default instance */
+  public static final MultiPolygonCodec INSTANCE = new MultiPolygonCodec();
+
+  public String className() {
+    return MultiPolygon.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.GEOMETRY && type.isAssignableFrom(MultiPolygon.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof MultiPolygon;
+  }
+
+  @Override
+  public MultiPolygon decodeText(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    return decodeBinary(buf, length, column, cal);
+  }
+
+  @Override
+  public MultiPolygon decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    if (column.getType() == DataType.GEOMETRY) {
+      buf.skip(4); // SRID
+      Geometry geo = Geometry.getGeometry(buf, length - 4, column);
+      if (geo instanceof MultiPolygon) return (MultiPolygon) geo;
+      throw new SQLDataException(
+          String.format(
+              "Geometric type %s cannot be decoded as MultiPolygon", geo.getClass().getName()));
+    }
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as MultiPolygon", column.getType()));
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeBytes(("ST_MPolyFromText('" + value.toString() + "')").getBytes());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    MultiPolygon mariadbMultiPolygon = (MultiPolygon) value;
+
+    int length = 13;
+    for (Polygon poly : mariadbMultiPolygon.getPolygons()) {
+      length += 9;
+      for (LineString ls : poly.getLines()) {
+        length += 4 + ls.getPoints().length * 16;
+      }
+    }
+
+    encoder.writeLength(length);
+    encoder.writeInt(0); // SRID
+    encoder.writeByte(0x01); // LITTLE ENDIAN
+    encoder.writeInt(6); // wkbMultiPolygon
+    encoder.writeInt(mariadbMultiPolygon.getPolygons().length); // nb polygon
+
+    for (Polygon poly : mariadbMultiPolygon.getPolygons()) {
+      encoder.writeByte(0x01); // LITTLE ENDIAN
+      encoder.writeInt(3); // wkbPolygon
+      encoder.writeInt(poly.getLines().length);
+      for (LineString ls : poly.getLines()) {
+        encoder.writeInt(ls.getPoints().length);
+        for (Point pt : ls.getPoints()) {
+          encoder.writeDouble(pt.getX());
+          encoder.writeDouble(pt.getY());
+        }
+      }
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/OffsetDateTimeCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/OffsetDateTimeCodec.java
new file mode 100644
index 0000000..3e702a4
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/OffsetDateTimeCodec.java
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZonedDateTime;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** OffsetDateTime codec */
+public class OffsetDateTimeCodec implements Codec<OffsetDateTime> {
+
+  /** default instance */
+  public static final OffsetDateTimeCodec INSTANCE = new OffsetDateTimeCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.DATETIME,
+          DataType.DATE,
+          DataType.YEAR,
+          DataType.TIMESTAMP,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.TIME,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return OffsetDateTime.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && type.isAssignableFrom(OffsetDateTime.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof OffsetDateTime;
+  }
+
+  @Override
+  public OffsetDateTime decodeText(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar calParam)
+      throws SQLDataException {
+
+    switch (column.getType()) {
+      case DATETIME:
+      case TIMESTAMP:
+        LocalDateTime localDateTime =
+            LocalDateTimeCodec.INSTANCE.decodeText(buf, length, column, calParam);
+        if (localDateTime == null) return null;
+        Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+        return localDateTime.atZone(cal.getTimeZone().toZoneId()).toOffsetDateTime();
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        String val = buf.readString(length);
+        try {
+          return OffsetDateTime.parse(val);
+        } catch (Throwable e) {
+          // eat
+        }
+        throw new SQLDataException(
+            String.format(
+                "value '%s' (%s) cannot be decoded as OffsetDateTime", val, column.getType()));
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format(
+                "value of type %s cannot be decoded as OffsetDateTime", column.getType()));
+    }
+  }
+
+  @Override
+  public OffsetDateTime decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar calParam)
+      throws SQLDataException {
+
+    switch (column.getType()) {
+      case DATETIME:
+      case TIMESTAMP:
+        LocalDateTime localDateTime =
+            LocalDateTimeCodec.INSTANCE.decodeBinary(buf, length, column, calParam);
+        if (localDateTime == null) return null;
+        Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+        return localDateTime.atZone(cal.getTimeZone().toZoneId()).toOffsetDateTime();
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        String val = buf.readString(length);
+        try {
+          return OffsetDateTime.parse(val);
+        } catch (Throwable e) {
+          // eat
+        }
+        throw new SQLDataException(
+            String.format(
+                "value '%s' (%s) cannot be decoded as OffsetDateTime", val, column.getType()));
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format(
+                "value of type %s cannot be decoded as OffsetDateTime", column.getType()));
+    }
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object val, Calendar calParam, Long maxLen)
+      throws IOException {
+    OffsetDateTime zdt = (OffsetDateTime) val;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    encoder.writeByte('\'');
+    encoder.writeAscii(
+        zdt.atZoneSameInstant(cal.getTimeZone().toZoneId())
+            .format(
+                zdt.getNano() != 0
+                    ? LocalDateTimeCodec.TIMESTAMP_FORMAT
+                    : LocalDateTimeCodec.TIMESTAMP_FORMAT_NO_FRACTIONAL));
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar calParam, Long maxLength)
+      throws IOException {
+    OffsetDateTime zdt = (OffsetDateTime) value;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    ZonedDateTime convertedZdt = zdt.atZoneSameInstant(cal.getTimeZone().toZoneId());
+    int nano = convertedZdt.getNano();
+    if (nano > 0) {
+      encoder.writeByte((byte) 11);
+      encoder.writeShort((short) convertedZdt.get(ChronoField.YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(convertedZdt.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(convertedZdt.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(convertedZdt.get(ChronoField.SECOND_OF_MINUTE));
+      encoder.writeInt(nano / 1000);
+    } else {
+      encoder.writeByte((byte) 7);
+      encoder.writeShort((short) convertedZdt.get(ChronoField.YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(convertedZdt.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(convertedZdt.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(convertedZdt.get(ChronoField.SECOND_OF_MINUTE));
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DATETIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/PointCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/PointCodec.java
new file mode 100644
index 0000000..c5c015b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/PointCodec.java
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.type.*;
+
+/** Point codec */
+public class PointCodec implements Codec<Point> {
+
+  /** default instance */
+  public static final PointCodec INSTANCE = new PointCodec();
+
+  public String className() {
+    return Point.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.GEOMETRY && type.isAssignableFrom(Point.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Point;
+  }
+
+  @Override
+  public Point decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return decodeBinary(buf, length, column, cal);
+  }
+
+  @Override
+  public Point decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    if (column.getType() == DataType.GEOMETRY) {
+      buf.skip(4); // SRID
+      Geometry geo = Geometry.getGeometry(buf, length - 4, column);
+      if (geo instanceof Point) return (Point) geo;
+      throw new SQLDataException(
+          String.format("Geometric type %s cannot be decoded as Point", geo.getClass().getName()));
+    }
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Point", column.getType()));
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeBytes(("ST_PointFromText('" + value.toString() + "')").getBytes());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    Point pt = (Point) value;
+    encoder.writeLength(25);
+    encoder.writeInt(0); // SRID
+    encoder.writeByte(0x01); // LITTLE ENDIAN
+    encoder.writeInt(1); // wkbPoint
+    encoder.writeDouble(pt.getX());
+    encoder.writeDouble(pt.getY());
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/PolygonCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/PolygonCodec.java
new file mode 100644
index 0000000..e0fda8f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/PolygonCodec.java
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.type.Geometry;
+import org.mariadb.jdbc.type.LineString;
+import org.mariadb.jdbc.type.Point;
+import org.mariadb.jdbc.type.Polygon;
+
+/** Polygon codec */
+public class PolygonCodec implements Codec<Polygon> {
+
+  /** default instance */
+  public static final PolygonCodec INSTANCE = new PolygonCodec();
+
+  public String className() {
+    return Polygon.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return column.getType() == DataType.GEOMETRY && type.isAssignableFrom(Polygon.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Polygon;
+  }
+
+  @Override
+  public Polygon decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return decodeBinary(buf, length, column, cal);
+  }
+
+  @Override
+  public Polygon decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    if (column.getType() == DataType.GEOMETRY) {
+      buf.skip(4); // SRID
+      Geometry geo = Geometry.getGeometry(buf, length - 4, column);
+      if (geo instanceof Polygon) return (Polygon) geo;
+      throw new SQLDataException(
+          String.format(
+              "Geometric type %s cannot be decoded as Polygon", geo.getClass().getName()));
+    }
+    buf.skip(length);
+    throw new SQLDataException(
+        String.format("Data type %s cannot be decoded as Polygon", column.getType()));
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeBytes(("ST_PolyFromText('" + value.toString() + "')").getBytes());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    Polygon poly = (Polygon) value;
+
+    int length = 13;
+    for (LineString ls : poly.getLines()) {
+      length += 4 + ls.getPoints().length * 16;
+    }
+
+    encoder.writeLength(length);
+    encoder.writeInt(0); // SRID
+    encoder.writeByte(0x01); // LITTLE ENDIAN
+    encoder.writeInt(3); // wkbPolygon
+    encoder.writeInt(poly.getLines().length);
+    for (LineString ls : poly.getLines()) {
+      encoder.writeInt(ls.getPoints().length);
+      for (Point pt : ls.getPoints()) {
+        encoder.writeDouble(pt.getX());
+        encoder.writeDouble(pt.getY());
+      }
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/ReaderCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/ReaderCodec.java
new file mode 100644
index 0000000..2b782dc
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/ReaderCodec.java
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** Reader codec */
+public class ReaderCodec implements Codec<Reader> {
+
+  /** default instance */
+  public static final ReaderCodec INSTANCE = new ReaderCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.STRING,
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(Reader.class);
+  }
+
+  public String className() {
+    return Reader.class.getName();
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Reader decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    switch (column.getType()) {
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        if (column.isBinary()) {
+          buf.skip(length);
+          throw new SQLDataException(
+              String.format("Data type %s cannot be decoded as Reader", column.getType()));
+        }
+        // expected fallthrough
+        // BLOB is considered as String if it has a collation (this is TEXT column)
+
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+        return new StringReader(buf.readString(length));
+
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Reader", column.getType()));
+    }
+  }
+
+  @Override
+  public Reader decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return decodeText(buf, length, column, cal);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Reader;
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object val, Calendar cal, Long maxLen)
+      throws IOException {
+    Reader reader = (Reader) val;
+    encoder.writeByte('\'');
+    char[] buf = new char[4096];
+    int len;
+    if (maxLen == null) {
+      while ((len = reader.read(buf)) >= 0) {
+        byte[] data = new String(buf, 0, len).getBytes(StandardCharsets.UTF_8);
+        encoder.writeBytesEscaped(
+            data,
+            data.length,
+            (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+      }
+    } else {
+      while ((len = reader.read(buf)) >= 0) {
+        byte[] data =
+            new String(buf, 0, Math.min(len, maxLen.intValue())).getBytes(StandardCharsets.UTF_8);
+        maxLen -= len;
+        encoder.writeBytesEscaped(
+            data,
+            data.length,
+            (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+      }
+    }
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object val, Calendar cal, Long maxLength)
+      throws IOException {
+    // prefer use of encodeLongData, because length is unknown
+    byte[] clobBytes = new byte[4096];
+    int pos = 0;
+    char[] buf = new char[4096];
+    Reader reader = (Reader) val;
+    int len;
+
+    long maxLen = maxLength != null ? maxLength : Long.MAX_VALUE;
+    while (maxLen > 0 && (len = reader.read(buf)) > 0) {
+      byte[] data =
+          new String(buf, 0, (int) Math.min(len, maxLen)).getBytes(StandardCharsets.UTF_8);
+      if (clobBytes.length - pos < data.length) {
+        byte[] newBlobBytes = new byte[clobBytes.length + 65536];
+        System.arraycopy(clobBytes, 0, newBlobBytes, 0, pos);
+        clobBytes = newBlobBytes;
+      }
+      System.arraycopy(data, 0, clobBytes, pos, data.length);
+      pos += data.length;
+      maxLen -= len;
+    }
+    encoder.writeLength(pos);
+    encoder.writeBytes(clobBytes, 0, pos);
+  }
+
+  @Override
+  public void encodeLongData(Writer encoder, Reader reader, Long maxLength) throws IOException {
+    char[] buf = new char[4096];
+    int len;
+    long maxLen = maxLength != null ? maxLength : Long.MAX_VALUE;
+    while (maxLen > 0 && (len = reader.read(buf)) >= 0) {
+      byte[] data =
+          new String(buf, 0, (int) Math.min(len, maxLen)).getBytes(StandardCharsets.UTF_8);
+      encoder.writeBytes(data, 0, data.length);
+      maxLen -= len;
+    }
+  }
+
+  @Override
+  public byte[] encodeData(Reader reader, Long maxLength) throws IOException {
+    ByteArrayOutputStream bb = new ByteArrayOutputStream();
+    char[] buf = new char[4096];
+    int len;
+    long maxLen = maxLength != null ? maxLength : Long.MAX_VALUE;
+    while (maxLen > 0 && (len = reader.read(buf)) >= 0) {
+      byte[] data =
+          new String(buf, 0, (int) Math.min(len, maxLen)).getBytes(StandardCharsets.UTF_8);
+      bb.write(data, 0, data.length);
+      maxLen -= len;
+    }
+    return bb.toByteArray();
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.VARSTRING.get();
+  }
+
+  public boolean canEncodeLongData() {
+    return true;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/ShortCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/ShortCodec.java
new file mode 100644
index 0000000..5dfcb93
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/ShortCodec.java
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Short codec */
+public class ShortCodec implements Codec<Short> {
+
+  /** default instance */
+  public static final ShortCodec INSTANCE = new ShortCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.OLDDECIMAL,
+          DataType.VARCHAR,
+          DataType.DECIMAL,
+          DataType.ENUM,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.MEDIUMINT,
+          DataType.INTEGER,
+          DataType.BIGINT,
+          DataType.BIT,
+          DataType.YEAR,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && ((type.isPrimitive() && type == Short.TYPE) || type.isAssignableFrom(Short.class));
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Short;
+  }
+
+  public String className() {
+    return Short.class.getName();
+  }
+
+  @Override
+  public Short decodeText(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeShortText(buffer, length);
+  }
+
+  @Override
+  public Short decodeBinary(
+      final ReadableByteBuf buffer,
+      final int length,
+      final ColumnDecoder column,
+      final Calendar cal)
+      throws SQLDataException {
+    return column.decodeShortBinary(buffer, length);
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeAscii(value.toString());
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    encoder.writeShort((Short) value);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.SMALLINT.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/StreamCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/StreamCodec.java
new file mode 100644
index 0000000..06a5a87
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/StreamCodec.java
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.*;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** InputStream codec */
+public class StreamCodec implements Codec<InputStream> {
+
+  /** default instance */
+  public static final StreamCodec INSTANCE = new StreamCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return InputStream.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(InputStream.class);
+  }
+
+  @Override
+  public InputStream decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    switch (column.getType()) {
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        ByteArrayInputStream is = new ByteArrayInputStream(buf.buf(), buf.pos(), length);
+        buf.skip(length);
+        return is;
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Stream", column.getType()));
+    }
+  }
+
+  @Override
+  public InputStream decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal) throws SQLDataException {
+    switch (column.getType()) {
+      case STRING:
+      case VARCHAR:
+      case VARSTRING:
+      case BLOB:
+      case TINYBLOB:
+      case MEDIUMBLOB:
+      case LONGBLOB:
+        ByteArrayInputStream is = new ByteArrayInputStream(buf.buf(), buf.pos(), length);
+        buf.skip(length);
+        return is;
+      default:
+        buf.skip(length);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Stream", column.getType()));
+    }
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof InputStream;
+  }
+
+  @Override
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeBytes(ByteArrayCodec.BINARY_PREFIX);
+    byte[] array = new byte[4096];
+    int len;
+    InputStream stream = (InputStream) value;
+
+    if (maxLen == null) {
+      while ((len = stream.read(array)) > 0) {
+        encoder.writeBytesEscaped(
+            array, len, (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+      }
+    } else {
+      while ((len = stream.read(array)) > 0 && maxLen > 0) {
+        encoder.writeBytesEscaped(
+            array,
+            Math.min(len, maxLen.intValue()),
+            (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+        maxLen -= len;
+      }
+    }
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    // length is not known
+    byte[] blobBytes = new byte[4096];
+    int pos = 0;
+    byte[] array = new byte[4096];
+    InputStream stream = (InputStream) value;
+
+    int len;
+    if (maxLength == null) {
+      while ((len = stream.read(array)) > 0) {
+        if (blobBytes.length - pos < len) {
+          byte[] newBlobBytes = new byte[blobBytes.length + 65536];
+          System.arraycopy(blobBytes, 0, newBlobBytes, 0, blobBytes.length);
+          blobBytes = newBlobBytes;
+        }
+        System.arraycopy(array, 0, blobBytes, pos, len);
+        pos += len;
+      }
+    } else {
+      long remainingLen = maxLength;
+      while ((len = stream.read(array)) > 0 && remainingLen > 0) {
+        len = Math.min((int) remainingLen, len);
+        if (blobBytes.length - pos < len) {
+          byte[] newBlobBytes = new byte[blobBytes.length + 65536];
+          System.arraycopy(blobBytes, 0, newBlobBytes, 0, blobBytes.length);
+          blobBytes = newBlobBytes;
+        }
+        System.arraycopy(array, 0, blobBytes, pos, len);
+        pos += len;
+        remainingLen -= len;
+      }
+    }
+    encoder.writeLength(pos);
+    encoder.writeBytes(blobBytes, 0, pos);
+  }
+
+  @Override
+  public void encodeLongData(Writer encoder, InputStream value, Long maxLength) throws IOException {
+    byte[] array = new byte[4096];
+    int len;
+    if (maxLength == null) {
+      while ((len = value.read(array)) > 0) {
+        encoder.writeBytes(array, 0, len);
+      }
+    } else {
+      long maxLen = maxLength;
+      while ((len = value.read(array)) > 0 && maxLen > 0) {
+        encoder.writeBytes(array, 0, Math.min(len, (int) maxLen));
+        maxLen -= len;
+      }
+    }
+  }
+
+  @Override
+  public byte[] encodeData(InputStream value, Long maxLength) throws IOException {
+    ByteArrayOutputStream bb = new ByteArrayOutputStream();
+    byte[] array = new byte[4096];
+    int len;
+    if (maxLength == null) {
+      while ((len = value.read(array)) > 0) {
+        bb.write(array, 0, len);
+      }
+    } else {
+      long maxLen = maxLength;
+      while ((len = value.read(array)) > 0 && maxLen > 0) {
+        bb.write(array, 0, Math.min(len, (int) maxLen));
+        maxLen -= len;
+      }
+    }
+    return bb.toByteArray();
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.BLOB.get();
+  }
+
+  public boolean canEncodeLongData() {
+    return true;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/StringCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/StringCodec.java
new file mode 100644
index 0000000..c09e5d0
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/StringCodec.java
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+/** String codec */
+public class StringCodec implements Codec<String> {
+
+  /** default instance */
+  public static final StringCodec INSTANCE = new StringCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.BIT,
+          DataType.OLDDECIMAL,
+          DataType.TINYINT,
+          DataType.SMALLINT,
+          DataType.INTEGER,
+          DataType.FLOAT,
+          DataType.DOUBLE,
+          DataType.TIMESTAMP,
+          DataType.BIGINT,
+          DataType.MEDIUMINT,
+          DataType.DATE,
+          DataType.TIME,
+          DataType.DATETIME,
+          DataType.YEAR,
+          DataType.NEWDATE,
+          DataType.JSON,
+          DataType.DECIMAL,
+          DataType.ENUM,
+          DataType.SET,
+          DataType.VARCHAR,
+          DataType.VARSTRING,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return String.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(String.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof String;
+  }
+
+  public String decodeText(
+      final ReadableByteBuf buf, final int length, final ColumnDecoder column, final Calendar cal)
+      throws SQLDataException {
+    return column.decodeStringText(buf, length, cal);
+  }
+
+  public String decodeBinary(
+      final ReadableByteBuf buf, final int length, final ColumnDecoder column, final Calendar cal)
+      throws SQLDataException {
+    return column.decodeStringBinary(buf, length, cal);
+  }
+
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeByte('\'');
+    encoder.writeStringEscaped(
+        maxLen == null ? value.toString() : value.toString().substring(0, maxLen.intValue()),
+        (context.getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) != 0);
+    encoder.writeByte('\'');
+  }
+
+  public void encodeBinary(Writer writer, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    byte[] b = value.toString().getBytes(StandardCharsets.UTF_8);
+    int len = maxLength != null ? Math.min(maxLength.intValue(), b.length) : b.length;
+    writer.writeLength(len);
+    writer.writeBytes(b, 0, len);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.VARSTRING.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/TimeCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/TimeCodec.java
new file mode 100644
index 0000000..0772bd2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/TimeCodec.java
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.sql.Time;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Time codec */
+public class TimeCodec implements Codec<Time> {
+
+  /** default instance */
+  public static final TimeCodec INSTANCE = new TimeCodec();
+  /** reference local date */
+  public static final LocalDate EPOCH_DATE = LocalDate.of(1970, 1, 1);
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.TIME,
+          DataType.DATETIME,
+          DataType.TIMESTAMP,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Time.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && type.isAssignableFrom(Time.class)
+        && !type.equals(java.util.Date.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Time;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Time decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return column.decodeTimeText(buf, length, cal);
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Time decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar calParam)
+      throws SQLDataException {
+    return column.decodeTimeBinary(buf, length, calParam);
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object val, Calendar providedCal, Long maxLen)
+      throws IOException {
+    Calendar cal = providedCal == null ? Calendar.getInstance() : providedCal;
+    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
+    sdf.setTimeZone(cal.getTimeZone());
+    String dateString = sdf.format(val);
+
+    encoder.writeByte('\'');
+    encoder.writeAscii(dateString);
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar providedCal, Long maxLength)
+      throws IOException {
+    Calendar cal = providedCal == null ? Calendar.getInstance() : providedCal;
+    synchronized (cal) {
+      cal.clear();
+      cal.setTime((Time) value);
+      cal.set(Calendar.DAY_OF_MONTH, 1);
+      if (cal.get(Calendar.MILLISECOND) > 0) {
+        encoder.writeByte((byte) 12);
+        encoder.writeByte((byte) 0);
+        encoder.writeInt(0);
+        encoder.writeByte((byte) cal.get(Calendar.HOUR_OF_DAY));
+        encoder.writeByte((byte) cal.get(Calendar.MINUTE));
+        encoder.writeByte((byte) cal.get(Calendar.SECOND));
+        encoder.writeInt(cal.get(Calendar.MILLISECOND) * 1000);
+      } else {
+        encoder.writeByte((byte) 8); // length
+        encoder.writeByte((byte) 0);
+        encoder.writeInt(0);
+        encoder.writeByte((byte) cal.get(Calendar.HOUR_OF_DAY));
+        encoder.writeByte((byte) cal.get(Calendar.MINUTE));
+        encoder.writeByte((byte) cal.get(Calendar.SECOND));
+      }
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.TIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/TimestampCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/TimestampCodec.java
new file mode 100644
index 0000000..b8389bb
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/TimestampCodec.java
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** Timestamp codec */
+public class TimestampCodec implements Codec<Timestamp> {
+
+  /** default instance */
+  public static final TimestampCodec INSTANCE = new TimestampCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.DATE,
+          DataType.NEWDATE,
+          DataType.DATETIME,
+          DataType.TIMESTAMP,
+          DataType.YEAR,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.TIME,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return Timestamp.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(Timestamp.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof Timestamp;
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Timestamp decodeText(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return column.decodeTimestampText(buf, length, cal);
+  }
+
+  @Override
+  @SuppressWarnings("fallthrough")
+  public Timestamp decodeBinary(ReadableByteBuf buf, int length, ColumnDecoder column, Calendar cal)
+      throws SQLDataException {
+    return column.decodeTimestampBinary(buf, length, cal);
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object val, Calendar providedCal, Long maxLen)
+      throws IOException {
+    Timestamp ts = (Timestamp) val;
+    Calendar cal = providedCal == null ? Calendar.getInstance() : providedCal;
+    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    sdf.setTimeZone(cal.getTimeZone());
+    String dateString = sdf.format(ts);
+
+    encoder.writeByte('\'');
+    encoder.writeAscii(dateString);
+
+    int microseconds = ts.getNanos() / 1000;
+    if (microseconds > 0) {
+      if (microseconds % 1000 == 0) {
+        encoder.writeAscii("." + Integer.toString(microseconds / 1000 + 1000).substring(1));
+      } else {
+        encoder.writeAscii("." + Integer.toString(microseconds + 1000000).substring(1));
+      }
+    }
+
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar providedCal, Long maxLength)
+      throws IOException {
+    Timestamp ts = (Timestamp) value;
+    Calendar cal = providedCal == null ? Calendar.getInstance() : providedCal;
+    synchronized (cal) {
+      cal.clear();
+      cal.setTimeInMillis(ts.getTime());
+      if (ts.getNanos() == 0) {
+        encoder.writeByte(7); // length
+        encoder.writeShort((short) cal.get(Calendar.YEAR));
+        encoder.writeByte((cal.get(Calendar.MONTH) + 1));
+        encoder.writeByte(cal.get(Calendar.DAY_OF_MONTH));
+        encoder.writeByte(cal.get(Calendar.HOUR_OF_DAY));
+        encoder.writeByte(cal.get(Calendar.MINUTE));
+        encoder.writeByte(cal.get(Calendar.SECOND));
+      } else {
+        encoder.writeByte(11); // length
+        encoder.writeShort((short) cal.get(Calendar.YEAR));
+        encoder.writeByte((cal.get(Calendar.MONTH) + 1));
+        encoder.writeByte(cal.get(Calendar.DAY_OF_MONTH));
+        encoder.writeByte(cal.get(Calendar.HOUR_OF_DAY));
+        encoder.writeByte(cal.get(Calendar.MINUTE));
+        encoder.writeByte(cal.get(Calendar.SECOND));
+        encoder.writeInt(ts.getNanos() / 1000);
+      }
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DATETIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/UuidCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/UuidCodec.java
new file mode 100644
index 0000000..8942fef
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/UuidCodec.java
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import java.util.UUID;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.Context;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** UUID codec */
+public class UuidCodec implements Codec<UUID> {
+
+  /** default instance */
+  public static final UuidCodec INSTANCE = new UuidCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(DataType.VARCHAR, DataType.VARSTRING, DataType.STRING);
+
+  public String className() {
+    return UUID.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType()) && type.isAssignableFrom(UUID.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof UUID;
+  }
+
+  public UUID decodeText(
+      final ReadableByteBuf buf, final int length, final ColumnDecoder column, final Calendar cal)
+      throws SQLDataException {
+    return UUID.fromString(column.decodeStringText(buf, length, cal));
+  }
+
+  public UUID decodeBinary(
+      final ReadableByteBuf buf, final int length, final ColumnDecoder column, final Calendar cal)
+      throws SQLDataException {
+    return UUID.fromString(column.decodeStringBinary(buf, length, cal));
+  }
+
+  public void encodeText(Writer encoder, Context context, Object value, Calendar cal, Long maxLen)
+      throws IOException {
+    encoder.writeByte('\'');
+    encoder.writeAscii(value.toString());
+    encoder.writeByte('\'');
+  }
+
+  public void encodeBinary(Writer writer, Object value, Calendar cal, Long maxLength)
+      throws IOException {
+    String valueSt = value.toString();
+    writer.writeLength(valueSt.length());
+    writer.writeAscii(valueSt);
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.VARSTRING.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/codec/ZonedDateTimeCodec.java b/src/main/java/org/mariadb/jdbc/plugin/codec/ZonedDateTimeCodec.java
new file mode 100644
index 0000000..df6e12b
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/codec/ZonedDateTimeCodec.java
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.codec;
+
+import java.io.IOException;
+import java.sql.SQLDataException;
+import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.EnumSet;
+import org.mariadb.jdbc.client.*;
+import org.mariadb.jdbc.client.socket.Writer;
+import org.mariadb.jdbc.plugin.Codec;
+
+/** ZonedDateTime codec */
+public class ZonedDateTimeCodec implements Codec<ZonedDateTime> {
+
+  /** default instance */
+  public static final ZonedDateTimeCodec INSTANCE = new ZonedDateTimeCodec();
+
+  private static final EnumSet<DataType> COMPATIBLE_TYPES =
+      EnumSet.of(
+          DataType.DATETIME,
+          DataType.DATE,
+          DataType.YEAR,
+          DataType.TIMESTAMP,
+          DataType.VARSTRING,
+          DataType.VARCHAR,
+          DataType.STRING,
+          DataType.TIME,
+          DataType.BLOB,
+          DataType.TINYBLOB,
+          DataType.MEDIUMBLOB,
+          DataType.LONGBLOB);
+
+  public String className() {
+    return ZonedDateTime.class.getName();
+  }
+
+  public boolean canDecode(ColumnDecoder column, Class<?> type) {
+    return COMPATIBLE_TYPES.contains(column.getType())
+        && type.isAssignableFrom(ZonedDateTime.class);
+  }
+
+  public boolean canEncode(Object value) {
+    return value instanceof ZonedDateTime;
+  }
+
+  @Override
+  public ZonedDateTime decodeText(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar calParam)
+      throws SQLDataException {
+    LocalDateTime localDateTime =
+        LocalDateTimeCodec.INSTANCE.decodeText(buf, length, column, calParam);
+    if (localDateTime == null) return null;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    return localDateTime.atZone(cal.getTimeZone().toZoneId());
+  }
+
+  @Override
+  public ZonedDateTime decodeBinary(
+      ReadableByteBuf buf, int length, ColumnDecoder column, Calendar calParam)
+      throws SQLDataException {
+    LocalDateTime localDateTime =
+        LocalDateTimeCodec.INSTANCE.decodeBinary(buf, length, column, calParam);
+    if (localDateTime == null) return null;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    return localDateTime.atZone(cal.getTimeZone().toZoneId());
+  }
+
+  @Override
+  public void encodeText(
+      Writer encoder, Context context, Object val, Calendar calParam, Long maxLen)
+      throws IOException {
+    ZonedDateTime zdt = (ZonedDateTime) val;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    encoder.writeByte('\'');
+    encoder.writeAscii(
+        zdt.withZoneSameInstant(cal.getTimeZone().toZoneId())
+            .format(
+                zdt.getNano() != 0
+                    ? LocalDateTimeCodec.TIMESTAMP_FORMAT
+                    : LocalDateTimeCodec.TIMESTAMP_FORMAT_NO_FRACTIONAL));
+    encoder.writeByte('\'');
+  }
+
+  @Override
+  public void encodeBinary(Writer encoder, Object value, Calendar calParam, Long maxLength)
+      throws IOException {
+    ZonedDateTime zdt = (ZonedDateTime) value;
+    Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
+    ZonedDateTime convertedZdt = zdt.withZoneSameInstant(cal.getTimeZone().toZoneId());
+    int nano = convertedZdt.getNano();
+    if (nano > 0) {
+      encoder.writeByte((byte) 11);
+      encoder.writeShort((short) convertedZdt.get(ChronoField.YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(convertedZdt.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(convertedZdt.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(convertedZdt.get(ChronoField.SECOND_OF_MINUTE));
+      encoder.writeInt(nano / 1000);
+    } else {
+      encoder.writeByte((byte) 7);
+      encoder.writeShort((short) convertedZdt.get(ChronoField.YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.MONTH_OF_YEAR));
+      encoder.writeByte(convertedZdt.get(ChronoField.DAY_OF_MONTH));
+      encoder.writeByte(convertedZdt.get(ChronoField.HOUR_OF_DAY));
+      encoder.writeByte(convertedZdt.get(ChronoField.MINUTE_OF_HOUR));
+      encoder.writeByte(convertedZdt.get(ChronoField.SECOND_OF_MINUTE));
+    }
+  }
+
+  public int getBinaryEncodeType() {
+    return DataType.DATETIME.get();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/credential/CredentialPluginLoader.java b/src/main/java/org/mariadb/jdbc/plugin/credential/CredentialPluginLoader.java
new file mode 100644
index 0000000..102e92e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/credential/CredentialPluginLoader.java
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.credential;
+
+import java.sql.SQLException;
+import java.util.ServiceLoader;
+import org.mariadb.jdbc.Driver;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+
+/**
+ * Provider to handle plugin authentication. This can allow library users to override our default
+ * Authentication provider.
+ */
+public final class CredentialPluginLoader {
+
+  private static final ServiceLoader<CredentialPlugin> loader =
+      ServiceLoader.load(CredentialPlugin.class, Driver.class.getClassLoader());
+
+  /**
+   * Get current Identity plugin according to option `identityType`.
+   *
+   * @param type identity plugin type
+   * @return identity plugin
+   * @throws SQLException if no identity plugin found with this type is in classpath
+   */
+  public static CredentialPlugin get(String type) throws SQLException {
+    if (type == null) return null;
+
+    for (CredentialPlugin implClass : loader) {
+      if (type.equals(implClass.type())) {
+        return implClass;
+      }
+    }
+    throw new SQLException(
+        "No identity plugin registered with the type \"" + type + "\".", "08004", 1251);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/credential/aws/AwsCredentialGenerator.java b/src/main/java/org/mariadb/jdbc/plugin/credential/aws/AwsCredentialGenerator.java
new file mode 100644
index 0000000..8930579
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/credential/aws/AwsCredentialGenerator.java
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.credential.aws;
+
+import java.util.Properties;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.plugin.Credential;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
+import software.amazon.awssdk.services.rds.RdsUtilities;
+
+/** AWS credential generator */
+public class AwsCredentialGenerator {
+
+  private final String authenticationToken;
+  private final String userName;
+
+  /**
+   * AWS Generator.
+   *
+   * @param nonMappedOptions non-standard options
+   * @param userName user
+   * @param hostAddress current server information
+   */
+  public AwsCredentialGenerator(
+      Properties nonMappedOptions, String userName, HostAddress hostAddress) {
+    // Build RDS IAM-auth token generator
+    this.userName = userName;
+    AwsCredentialsProvider awsCredentialsProvider;
+    String accessKeyId = nonMappedOptions.getProperty("accessKeyId");
+    String secretKey = nonMappedOptions.getProperty("secretKey");
+    String region = nonMappedOptions.getProperty("region");
+
+    if (accessKeyId != null && secretKey != null) {
+      awsCredentialsProvider =
+          StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKeyId, secretKey));
+    } else {
+      awsCredentialsProvider = DefaultCredentialsProvider.builder().build();
+    }
+
+    RdsUtilities utilities =
+        RdsUtilities.builder()
+            .credentialsProvider(awsCredentialsProvider)
+            .region(
+                region != null
+                    ? Region.of(region)
+                    : new DefaultAwsRegionProviderChain().getRegion())
+            .build();
+
+    this.authenticationToken =
+        utilities.generateAuthenticationToken(
+            builder -> {
+              builder
+                  .username(userName)
+                  .hostname(hostAddress.host)
+                  .port(hostAddress.port)
+                  .credentialsProvider(awsCredentialsProvider);
+            });
+  }
+
+  /**
+   * Generate authentication token
+   *
+   * @return token
+   */
+  public Credential getToken() {
+    return new Credential(userName, authenticationToken);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/credential/aws/AwsIamCredentialPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/credential/aws/AwsIamCredentialPlugin.java
new file mode 100644
index 0000000..4524297
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/credential/aws/AwsIamCredentialPlugin.java
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.credential.aws;
+
+import static java.time.LocalDateTime.now;
+
+import java.sql.SQLException;
+import java.time.LocalDateTime;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.plugin.Credential;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+
+/**
+ * Permit AWS database IAM authentication.
+ *
+ * <p>Token is generated using IAM credential and region.
+ *
+ * <p>Implementation use SDK DefaultAWSCredentialsProviderChain and DefaultAwsRegionProviderChain
+ * (environment variable / system properties, files, ...) or using connection string options :
+ * accessKeyId, secretKey, region.
+ *
+ * @see <a
+ *     href="https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html">DefaultCredentialsProvider</a>
+ * @see <a
+ *     href="https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/regions/providers/DefaultAwsRegionProviderChain.html">DefaultAwsRegionProviderChain</a>
+ */
+public class AwsIamCredentialPlugin implements CredentialPlugin {
+
+  private static final int TOKEN_TTL = 10;
+
+  private static final Map<KeyCache, IdentityExpire> cache = new ConcurrentHashMap<>();
+
+  private AwsCredentialGenerator generator;
+  private KeyCache key;
+
+  @Override
+  public String type() {
+    return "AWS-IAM";
+  }
+
+  @Override
+  public boolean mustUseSsl() {
+    return true;
+  }
+
+  @Override
+  public CredentialPlugin initialize(Configuration conf, String userName, HostAddress hostAddress)
+      throws SQLException {
+    try {
+      Class.forName("software.amazon.awssdk.auth.credentials.AwsBasicCredentials");
+    } catch (ClassNotFoundException ex) {
+      throw new SQLException(
+          "Identity plugin 'AWS-IAM' is used without having AWS SDK in "
+              + "classpath. "
+              + "Please add 'software.amazon.awssdk:rds' to classpath");
+    }
+    this.generator = new AwsCredentialGenerator(conf.nonMappedOptions(), conf.user(), hostAddress);
+    this.key = new KeyCache(conf, conf.user(), hostAddress);
+    return this;
+  }
+
+  @Override
+  public Credential get() {
+    IdentityExpire val = cache.get(key);
+    if (val != null && val.isValid()) {
+      return val.getCredential();
+    }
+
+    Credential credential = generator.getToken();
+    cache.put(key, new IdentityExpire(credential));
+    return credential;
+  }
+
+  private static class IdentityExpire {
+
+    private final LocalDateTime expiration;
+    private final Credential credential;
+
+    public IdentityExpire(Credential credential) {
+      this.credential = credential;
+      expiration = now().plusMinutes(TOKEN_TTL);
+    }
+
+    public boolean isValid() {
+      return expiration.isAfter(now());
+    }
+
+    public Credential getCredential() {
+      return credential;
+    }
+  }
+
+  private static class KeyCache {
+    private final Configuration conf;
+    private final String userName;
+    private final HostAddress hostAddress;
+
+    public KeyCache(Configuration conf, String userName, HostAddress hostAddress) {
+      this.conf = conf;
+      this.userName = userName;
+      this.hostAddress = hostAddress;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
+      KeyCache keyCache = (KeyCache) o;
+      return conf.equals(keyCache.conf)
+          && Objects.equals(userName, keyCache.userName)
+          && hostAddress.equals(keyCache.hostAddress);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(conf, userName, hostAddress);
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/credential/env/EnvCredentialPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/credential/env/EnvCredentialPlugin.java
new file mode 100644
index 0000000..883bb13
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/credential/env/EnvCredentialPlugin.java
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.credential.env;
+
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.plugin.Credential;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+
+/**
+ * Authentication using environment variable.
+ *
+ * <p>default implementation use environment variable MARIADB_USER and MARIADB_PWD
+ *
+ * <p>example : `jdbc:mariadb://host/db?credentialType=ENV`
+ *
+ * <p>2 options `userKey` and `pwdKey` permits indicating which environment variable to use.
+ */
+public class EnvCredentialPlugin implements CredentialPlugin {
+
+  private Configuration conf;
+  private String userName;
+
+  @Override
+  public String type() {
+    return "ENV";
+  }
+
+  @Override
+  public CredentialPlugin initialize(Configuration conf, String userName, HostAddress hostAddress) {
+    this.conf = conf;
+    this.userName = userName;
+    return this;
+  }
+
+  @Override
+  public Credential get() {
+
+    String userKey = this.conf.nonMappedOptions().getProperty("userKey");
+    String pwdKey = this.conf.nonMappedOptions().getProperty("pwdKey");
+    String envUser = System.getenv(userKey != null ? userKey : "MARIADB_USER");
+    return new Credential(
+        envUser == null ? userName : envUser,
+        System.getenv(pwdKey != null ? pwdKey : "MARIADB_PWD"));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/credential/system/PropertiesCredentialPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/credential/system/PropertiesCredentialPlugin.java
new file mode 100644
index 0000000..2ef777d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/credential/system/PropertiesCredentialPlugin.java
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.credential.system;
+
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.plugin.Credential;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+
+/**
+ * Authentication using java system properties.
+ *
+ * <p>default implementation use system properties `mariadb.user` and `mariadb.pwd`
+ *
+ * <p>example : `jdbc:mariadb://host/db?credentialType=PROPERTY`
+ *
+ * <p>2 options `userKey` and `pwdKey` permits indicating which system properties to use .
+ */
+public class PropertiesCredentialPlugin implements CredentialPlugin {
+
+  private Configuration conf;
+  private String userName;
+
+  @Override
+  public String type() {
+    return "PROPERTY";
+  }
+
+  @Override
+  public CredentialPlugin initialize(Configuration conf, String userName, HostAddress hostAddress) {
+    this.conf = conf;
+    this.userName = userName;
+    return this;
+  }
+
+  @Override
+  public Credential get() {
+
+    String userKey = this.conf.nonMappedOptions().getProperty("userKey");
+    String pwdKey = this.conf.nonMappedOptions().getProperty("pwdKey");
+    String propUser = System.getProperty(userKey != null ? userKey : "mariadb.user");
+
+    return new Credential(
+        propUser == null ? userName : propUser,
+        System.getProperty(pwdKey != null ? pwdKey : "mariadb.pwd"));
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/tls/TlsSocketPluginLoader.java b/src/main/java/org/mariadb/jdbc/plugin/tls/TlsSocketPluginLoader.java
new file mode 100644
index 0000000..772c427
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/tls/TlsSocketPluginLoader.java
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.tls;
+
+import java.sql.SQLException;
+import java.util.ServiceLoader;
+import org.mariadb.jdbc.plugin.TlsSocketPlugin;
+import org.mariadb.jdbc.plugin.tls.main.DefaultTlsSocketPlugin;
+
+/** TLS plugin loader */
+public final class TlsSocketPluginLoader {
+
+  /**
+   * Get authentication plugin from type String. Customs authentication plugin can be added
+   * implementing AuthenticationPlugin and registering new type in resources services.
+   *
+   * @param type authentication plugin type
+   * @return Authentication plugin corresponding to type
+   * @throws SQLException if no authentication plugin in classpath have indicated type
+   */
+  public static TlsSocketPlugin get(String type) throws SQLException {
+    if (type == null) return new DefaultTlsSocketPlugin();
+
+    ServiceLoader<TlsSocketPlugin> loader = ServiceLoader.load(TlsSocketPlugin.class);
+    for (TlsSocketPlugin implClass : loader) {
+      if (type.equals(implClass.type())) {
+        return implClass;
+      }
+    }
+    throw new SQLException(
+        "Client has not found any TLS factory plugin with name '" + type + "'.", "08004", 1251);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/plugin/tls/main/DefaultTlsSocketPlugin.java b/src/main/java/org/mariadb/jdbc/plugin/tls/main/DefaultTlsSocketPlugin.java
new file mode 100644
index 0000000..feab50f
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/plugin/tls/main/DefaultTlsSocketPlugin.java
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.plugin.tls.main;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.UUID;
+import javax.net.ssl.*;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.client.tls.HostnameVerifier;
+import org.mariadb.jdbc.client.tls.MariaDbX509KeyManager;
+import org.mariadb.jdbc.client.tls.MariaDbX509TrustingManager;
+import org.mariadb.jdbc.export.ExceptionFactory;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.plugin.TlsSocketPlugin;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** Default TLS socket plugin */
+public class DefaultTlsSocketPlugin implements TlsSocketPlugin {
+  private static final Logger logger = Loggers.getLogger(DefaultTlsSocketPlugin.class);
+
+  private static KeyManager loadClientCerts(
+      String keyStoreUrl,
+      String keyStorePassword,
+      String storeType,
+      ExceptionFactory exceptionFactory)
+      throws SQLException {
+
+    try {
+      try (InputStream inStream = loadFromUrl(keyStoreUrl)) {
+        char[] keyStorePasswordChars =
+            keyStorePassword == null ? null : keyStorePassword.toCharArray();
+        KeyStore ks =
+            KeyStore.getInstance(storeType != null ? storeType : KeyStore.getDefaultType());
+        ks.load(inStream, keyStorePasswordChars);
+        return new MariaDbX509KeyManager(ks, keyStorePasswordChars);
+      }
+    } catch (IOException | GeneralSecurityException ex) {
+      throw exceptionFactory.create(
+          "Failed to read keyStore file. Option keyStore=" + keyStoreUrl, "08000", ex);
+    }
+  }
+
+  private static InputStream loadFromUrl(String keyStoreUrl) throws FileNotFoundException {
+    try {
+      return new URL(keyStoreUrl).openStream();
+    } catch (IOException ioexception) {
+      return new FileInputStream(keyStoreUrl);
+    }
+  }
+
+  @Override
+  public String type() {
+    return "DEFAULT";
+  }
+
+  @Override
+  public SSLSocketFactory getSocketFactory(Configuration conf, ExceptionFactory exceptionFactory)
+      throws SQLException {
+
+    TrustManager[] trustManager = null;
+    KeyManager[] keyManager = null;
+
+    if (conf.sslMode() == SslMode.TRUST) {
+      trustManager = new X509TrustManager[] {new MariaDbX509TrustingManager()};
+    } else { // if certificate is provided, load it.
+      // if not, relying on default truststore
+      if (conf.serverSslCert() != null) {
+
+        KeyStore ks;
+        try {
+          ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        } catch (GeneralSecurityException generalSecurityEx) {
+          throw exceptionFactory.create(
+              "Failed to create keystore instance", "08000", generalSecurityEx);
+        }
+
+        try (InputStream inStream = getInputStreamFromPath(conf.serverSslCert())) {
+          // generate a keyStore from the provided cert
+
+          // Note: KeyStore requires it be loaded even if you don't load anything into it
+          // (will be initialized with "javax.net.ssl.trustStore") values.
+          ks.load(null);
+          CertificateFactory cf = CertificateFactory.getInstance("X.509");
+          Collection<? extends Certificate> caList = cf.generateCertificates(inStream);
+          for (Certificate ca : caList) {
+            ks.setCertificateEntry(UUID.randomUUID().toString(), ca);
+          }
+
+          TrustManagerFactory tmf =
+              TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+          tmf.init(ks);
+          for (TrustManager tm : tmf.getTrustManagers()) {
+            if (tm instanceof X509TrustManager) {
+              trustManager = new X509TrustManager[] {(X509TrustManager) tm};
+              break;
+            }
+          }
+
+          if (trustManager == null) {
+            throw new SQLException("No X509TrustManager found");
+          }
+
+        } catch (IOException ioEx) {
+          throw exceptionFactory.create("Failed load keyStore", "08000", ioEx);
+        } catch (GeneralSecurityException generalSecurityEx) {
+          throw exceptionFactory.create(
+              "Failed to store certificate from serverSslCert into a keyStore",
+              "08000",
+              generalSecurityEx);
+        }
+      }
+    }
+
+    if (conf.keyStore() != null) {
+      keyManager =
+          new KeyManager[] {
+            loadClientCerts(
+                conf.keyStore(), conf.keyStorePassword(), conf.keyStoreType(), exceptionFactory)
+          };
+    } else {
+      String keyStore = System.getProperty("javax.net.ssl.keyStore");
+      String keyStorePassword =
+          System.getProperty("javax.net.ssl.keyStorePassword", conf.keyStorePassword());
+      String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType", conf.keyStoreType());
+      if (keyStore != null) {
+        try {
+          keyManager =
+              new KeyManager[] {
+                loadClientCerts(keyStore, keyStorePassword, keyStoreType, exceptionFactory)
+              };
+        } catch (SQLException queryException) {
+          keyManager = null;
+          logger.error("Error loading key manager from system properties", queryException);
+        }
+      }
+    }
+
+    try {
+      SSLContext sslContext = SSLContext.getInstance("TLS");
+      sslContext.init(keyManager, trustManager, null);
+      return sslContext.getSocketFactory();
+    } catch (KeyManagementException keyManagementEx) {
+      throw exceptionFactory.create("Could not initialize SSL context", "08000", keyManagementEx);
+    } catch (NoSuchAlgorithmException noSuchAlgorithmEx) {
+      throw exceptionFactory.create(
+          "SSLContext TLS Algorithm not unknown", "08000", noSuchAlgorithmEx);
+    }
+  }
+
+  private static InputStream getInputStreamFromPath(String path) throws IOException {
+    try {
+      return new URL(path).openStream();
+    } catch (MalformedURLException e) {
+      if (path.startsWith("-----")) {
+        return new ByteArrayInputStream(path.getBytes());
+      } else {
+        File f = new File(path);
+        if (f.exists() && !f.isDirectory()) {
+          return f.toURI().toURL().openStream();
+        }
+      }
+      throw new IOException(
+          String.format("Wrong value for option `serverSslCert` (value: '%s')", path), e);
+    }
+  }
+
+  @Override
+  public void verify(String host, SSLSession session, long serverThreadId) throws SSLException {
+    try {
+      Certificate[] certs = session.getPeerCertificates();
+      X509Certificate cert = (X509Certificate) certs[0];
+      HostnameVerifier.verify(host, cert, serverThreadId);
+    } catch (SSLException ex) {
+      logger.info(ex.getMessage(), ex);
+      throw ex;
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/pool/MariaDbInnerPoolConnection.java b/src/main/java/org/mariadb/jdbc/pool/MariaDbInnerPoolConnection.java
new file mode 100644
index 0000000..ae4d996
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/pool/MariaDbInnerPoolConnection.java
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.pool;
+
+import java.util.concurrent.atomic.AtomicLong;
+import javax.sql.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.MariaDbPoolConnection;
+
+/**
+ * MariaDB pool connection for internal pool permit to add a last used information, to remove
+ * connection after staying in pool for long time.
+ */
+public class MariaDbInnerPoolConnection extends MariaDbPoolConnection {
+  private final AtomicLong lastUsed;
+
+  /**
+   * Constructor.
+   *
+   * @param connection connection to retrieve connection options
+   */
+  public MariaDbInnerPoolConnection(Connection connection) {
+    super(connection);
+    lastUsed = new AtomicLong(System.nanoTime());
+  }
+
+  /**
+   * Indicate last time this pool connection has been used.
+   *
+   * @return current last used time (nano).
+   */
+  public AtomicLong getLastUsed() {
+    return lastUsed;
+  }
+
+  /** Set last poolConnection use to now. */
+  public void lastUsedToNow() {
+    lastUsed.set(System.nanoTime());
+  }
+
+  /** Reset last used time, to ensure next retrieval will validate connection before borrowing */
+  public void ensureValidation() {
+    lastUsed.set(0L);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/pool/Pool.java b/src/main/java/org/mariadb/jdbc/pool/Pool.java
new file mode 100644
index 0000000..4240149
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/pool/Pool.java
@@ -0,0 +1,569 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.pool;
+
+import java.lang.management.ManagementFactory;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.sql.ConnectionEvent;
+import javax.sql.ConnectionEventListener;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Driver;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+/** MariaDB Pool */
+@SuppressWarnings({"unchecked"})
+public class Pool implements AutoCloseable, PoolMBean {
+
+  private static final Logger logger = Loggers.getLogger(Pool.class);
+
+  private static final int POOL_STATE_OK = 0;
+  private static final int POOL_STATE_CLOSING = 1;
+
+  private final AtomicInteger poolState = new AtomicInteger();
+
+  private final Configuration conf;
+  private final AtomicInteger pendingRequestNumber = new AtomicInteger();
+  private final AtomicInteger totalConnection = new AtomicInteger();
+
+  private final LinkedBlockingDeque<MariaDbInnerPoolConnection> idleConnections;
+  private final ThreadPoolExecutor connectionAppender;
+  private final BlockingQueue<Runnable> connectionAppenderQueue;
+
+  private final String poolTag;
+  private final ScheduledThreadPoolExecutor poolExecutor;
+  private final ScheduledFuture<?> scheduledFuture;
+
+  private int waitTimeout;
+
+  /**
+   * Create pool from configuration.
+   *
+   * @param conf configuration parser
+   * @param poolIndex pool index to permit distinction of thread name
+   * @param poolExecutor pools common executor
+   */
+  public Pool(Configuration conf, int poolIndex, ScheduledThreadPoolExecutor poolExecutor) {
+
+    this.conf = conf;
+    poolTag = generatePoolTag(poolIndex);
+
+    // one thread to add new connection to pool.
+    connectionAppenderQueue = new ArrayBlockingQueue<>(conf.maxPoolSize());
+    connectionAppender =
+        new ThreadPoolExecutor(
+            1,
+            1,
+            10,
+            TimeUnit.SECONDS,
+            connectionAppenderQueue,
+            new PoolThreadFactory(poolTag + "-appender"));
+    connectionAppender.allowCoreThreadTimeOut(true);
+    // create workers, since driver only interact with queue after that (i.e. not using .execute() )
+    connectionAppender.prestartCoreThread();
+
+    idleConnections = new LinkedBlockingDeque<>();
+    int minDelay =
+        Integer.parseInt(conf.nonMappedOptions().getProperty("testMinRemovalDelay", "30"));
+    int scheduleDelay = Math.min(minDelay, conf.maxIdleTime() / 2);
+    this.poolExecutor = poolExecutor;
+    scheduledFuture =
+        poolExecutor.scheduleAtFixedRate(
+            this::removeIdleTimeoutConnection, scheduleDelay, scheduleDelay, TimeUnit.SECONDS);
+
+    if (conf.registerJmxPool()) {
+      try {
+        registerJmx();
+      } catch (Exception ex) {
+        logger.error("pool " + poolTag + " not registered due to exception : " + ex.getMessage());
+      }
+    }
+
+    // create minimal connection in pool
+    try {
+      for (int i = 0; i < Math.max(1, conf.minPoolSize()); i++) {
+        addConnection();
+      }
+      waitTimeout = 28800;
+      if (!idleConnections.isEmpty()) {
+        Statement stmt = idleConnections.getFirst().getConnection().createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT @@wait_timeout");
+        if (rs.next()) waitTimeout = rs.getInt(1);
+      }
+    } catch (SQLException sqle) {
+      logger.error("error initializing pool connection", sqle);
+    }
+  }
+
+  /**
+   * Add new connection if needed. Only one thread create new connection, so new connection request
+   * will wait to newly created connection or for a released connection.
+   */
+  private void addConnectionRequest() {
+    if (totalConnection.get() < conf.maxPoolSize() && poolState.get() == POOL_STATE_OK) {
+
+      // ensure to have one worker if was timeout
+      connectionAppender.prestartCoreThread();
+      boolean unused =
+          connectionAppenderQueue.offer(
+              () -> {
+                if ((totalConnection.get() < conf.minPoolSize() || pendingRequestNumber.get() > 0)
+                    && totalConnection.get() < conf.maxPoolSize()) {
+                  try {
+                    addConnection();
+                  } catch (SQLException sqle) {
+                    logger.error("error adding connection to pool", sqle);
+                  }
+                }
+              });
+    }
+  }
+
+  /**
+   * Removing idle connection. Close them and recreate connection to reach minimal number of
+   * connection.
+   */
+  private void removeIdleTimeoutConnection() {
+
+    // descending iterator since first from queue are the first to be used
+    Iterator<MariaDbInnerPoolConnection> iterator = idleConnections.descendingIterator();
+
+    MariaDbInnerPoolConnection item;
+
+    while (iterator.hasNext()) {
+      item = iterator.next();
+
+      long idleTime = System.nanoTime() - item.getLastUsed().get();
+      boolean timedOut = idleTime > TimeUnit.SECONDS.toNanos(conf.maxIdleTime());
+
+      boolean shouldBeReleased = false;
+      Connection con = item.getConnection();
+      if (waitTimeout > 0) {
+
+        // idle time is reaching server @@wait_timeout
+        if (idleTime > TimeUnit.SECONDS.toNanos(waitTimeout - 45)) {
+          shouldBeReleased = true;
+        }
+
+        //  idle has reach option maxIdleTime value and pool has more connections than minPoolSiz
+        if (timedOut && totalConnection.get() > conf.minPoolSize()) {
+          shouldBeReleased = true;
+        }
+
+      } else if (timedOut) {
+        shouldBeReleased = true;
+      }
+
+      if (shouldBeReleased && idleConnections.remove(item)) {
+
+        totalConnection.decrementAndGet();
+        silentCloseConnection(con);
+        addConnectionRequest();
+        if (logger.isDebugEnabled()) {
+          logger.debug(
+              "pool {} connection {} removed due to inactivity (total:{}, active:{}, pending:{})",
+              poolTag,
+              con.getThreadId(),
+              totalConnection.get(),
+              getActiveConnections(),
+              pendingRequestNumber.get());
+        }
+      }
+    }
+  }
+
+  /**
+   * Create new connection.
+   *
+   * @throws SQLException if connection creation failed
+   */
+  private void addConnection() throws SQLException {
+
+    // create new connection
+    Connection connection = Driver.connect(conf);
+    MariaDbInnerPoolConnection item = new MariaDbInnerPoolConnection(connection);
+    item.addConnectionEventListener(
+        new ConnectionEventListener() {
+
+          @Override
+          public void connectionClosed(ConnectionEvent event) {
+            MariaDbInnerPoolConnection item = (MariaDbInnerPoolConnection) event.getSource();
+            if (poolState.get() == POOL_STATE_OK) {
+              try {
+                if (!idleConnections.contains(item)) {
+                  item.getConnection().setPoolConnection(null);
+                  item.getConnection().reset();
+                  idleConnections.addFirst(item);
+                  item.getConnection().setPoolConnection(item);
+                }
+              } catch (SQLException sqle) {
+
+                // sql exception during reset, removing connection from pool
+                totalConnection.decrementAndGet();
+                silentCloseConnection(item.getConnection());
+                logger.debug(
+                    "connection {} removed from pool {} due to error during reset (total:{},"
+                        + " active:{}, pending:{})",
+                    item.getConnection().getThreadId(),
+                    poolTag,
+                    totalConnection.get(),
+                    getActiveConnections(),
+                    pendingRequestNumber.get());
+              }
+            } else {
+              // pool is closed, should then not be rendered to pool, but closed.
+              try {
+                item.getConnection().close();
+              } catch (SQLException sqle) {
+                // eat
+              }
+              totalConnection.decrementAndGet();
+            }
+          }
+
+          @Override
+          public void connectionErrorOccurred(ConnectionEvent event) {
+
+            MariaDbInnerPoolConnection item = ((MariaDbInnerPoolConnection) event.getSource());
+            totalConnection.decrementAndGet();
+            boolean unused = idleConnections.remove(item);
+
+            // ensure that other connection will be validated before being use
+            // since one connection failed, better to assume the other might as well
+            idleConnections.forEach(MariaDbInnerPoolConnection::ensureValidation);
+
+            silentCloseConnection(item.getConnection());
+            addConnectionRequest();
+            logger.debug(
+                "connection {} removed from pool {} due to having throw a Connection exception"
+                    + " (total:{}, active:{}, pending:{})",
+                item.getConnection().getThreadId(),
+                poolTag,
+                totalConnection.get(),
+                getActiveConnections(),
+                pendingRequestNumber.get());
+          }
+        });
+    if (poolState.get() == POOL_STATE_OK
+        && totalConnection.incrementAndGet() <= conf.maxPoolSize()) {
+      idleConnections.addFirst(item);
+
+      if (logger.isDebugEnabled()) {
+        logger.debug(
+            "pool {} new physical connection {} created (total:{}, active:{}, pending:{})",
+            poolTag,
+            connection.getThreadId(),
+            totalConnection.get(),
+            getActiveConnections(),
+            pendingRequestNumber.get());
+      }
+      return;
+    }
+
+    silentCloseConnection(connection);
+  }
+
+  /**
+   * Get an existing idle connection in pool.
+   *
+   * @return an IDLE connection.
+   */
+  private MariaDbInnerPoolConnection getIdleConnection(long timeout, TimeUnit timeUnit)
+      throws InterruptedException {
+
+    while (true) {
+      MariaDbInnerPoolConnection item =
+          (timeout == 0)
+              ? idleConnections.pollFirst()
+              : idleConnections.pollFirst(timeout, timeUnit);
+
+      if (item != null) {
+        try {
+          if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - item.getLastUsed().get())
+              > conf.poolValidMinDelay()) {
+
+            // validate connection
+            if (item.getConnection().isValid(10)) { // 10 seconds timeout
+              item.lastUsedToNow();
+              return item;
+            }
+
+          } else {
+
+            // connection has been retrieved recently -> skip connection validation
+            item.lastUsedToNow();
+            return item;
+          }
+
+        } catch (SQLException sqle) {
+          // eat
+        }
+
+        // validation failed
+        silentAbortConnection(item.getConnection());
+        addConnectionRequest();
+        if (logger.isDebugEnabled()) {
+          logger.debug(
+              "pool {} connection {} removed from pool due to failed validation (total:{},"
+                  + " active:{}, pending:{})",
+              poolTag,
+              item.getConnection().getThreadId(),
+              totalConnection.get(),
+              getActiveConnections(),
+              pendingRequestNumber.get());
+        }
+        continue;
+      }
+
+      return null;
+    }
+  }
+
+  private void silentCloseConnection(Connection con) {
+    con.setPoolConnection(null);
+    try {
+      con.close();
+    } catch (SQLException ex) {
+      // eat exception
+    }
+  }
+
+  private void silentAbortConnection(Connection con) {
+    con.setPoolConnection(null);
+    try {
+      con.abort(poolExecutor);
+    } catch (SQLException ex) {
+      // eat exception
+    }
+  }
+
+  /**
+   * Retrieve new connection. If possible return idle connection, if not, stack connection query,
+   * ask for a connection creation, and loop until a connection become idle / a new connection is
+   * created.
+   *
+   * @return a connection object
+   * @throws SQLException if no connection is created when reaching timeout (connectTimeout option)
+   */
+  public MariaDbInnerPoolConnection getPoolConnection() throws SQLException {
+    pendingRequestNumber.incrementAndGet();
+    MariaDbInnerPoolConnection poolConnection;
+    try {
+      // try to get Idle connection if any (with a very small timeout)
+      if ((poolConnection =
+              getIdleConnection(totalConnection.get() > 4 ? 0 : 50, TimeUnit.MICROSECONDS))
+          != null) {
+        return poolConnection;
+      }
+
+      // ask for new connection creation if max is not reached
+      addConnectionRequest();
+
+      // try to create new connection if semaphore permit it
+      if ((poolConnection =
+              getIdleConnection(
+                  TimeUnit.MILLISECONDS.toNanos(conf.connectTimeout()), TimeUnit.NANOSECONDS))
+          != null) {
+        return poolConnection;
+      }
+
+      throw new SQLException(
+          String.format(
+              "No connection available within the specified time (option 'connectTimeout': %s ms)",
+              NumberFormat.getInstance().format(conf.connectTimeout())));
+
+    } catch (InterruptedException interrupted) {
+      throw new SQLException("Thread was interrupted", "70100", interrupted);
+    } finally {
+      pendingRequestNumber.decrementAndGet();
+    }
+  }
+
+  /**
+   * Get new connection from pool if user and password correspond to pool. If username and password
+   * are different from pool, will return a dedicated connection.
+   *
+   * @param username username
+   * @param password password
+   * @return connection
+   * @throws SQLException if any error occur during connection
+   */
+  public MariaDbInnerPoolConnection getPoolConnection(String username, String password)
+      throws SQLException {
+    if (username == null
+        ? conf.user() == null
+        : username.equals(conf.user()) && (password == null || password.isEmpty())
+            ? conf.password() == null
+            : password.equals(conf.password())) {
+      return getPoolConnection();
+    }
+
+    Configuration tmpConf = conf.clone(username, password);
+    return new MariaDbInnerPoolConnection(Driver.connect(tmpConf));
+  }
+
+  private String generatePoolTag(int poolIndex) {
+    if (conf.poolName() == null) {
+      return "MariaDB-pool";
+    }
+    return conf.poolName() + "-" + poolIndex;
+  }
+
+  /**
+   * Get current configuration
+   *
+   * @return configuration
+   */
+  public Configuration getConf() {
+    return conf;
+  }
+
+  /** Close pool and underlying connections. */
+  @Override
+  public void close() {
+    try {
+      synchronized (this) {
+        Pools.remove(this);
+        poolState.set(POOL_STATE_CLOSING);
+        pendingRequestNumber.set(0);
+
+        scheduledFuture.cancel(false);
+        connectionAppender.shutdown();
+
+        try {
+          boolean unused = connectionAppender.awaitTermination(10, TimeUnit.SECONDS);
+        } catch (InterruptedException i) {
+          // eat
+        }
+
+        if (logger.isInfoEnabled()) {
+          logger.debug(
+              "closing pool {} (total:{}, active:{}, pending:{})",
+              poolTag,
+              totalConnection.get(),
+              getActiveConnections(),
+              pendingRequestNumber.get());
+        }
+
+        ExecutorService connectionRemover =
+            new ThreadPoolExecutor(
+                totalConnection.get(),
+                conf.maxPoolSize(),
+                10,
+                TimeUnit.SECONDS,
+                new LinkedBlockingQueue<>(conf.maxPoolSize()),
+                new PoolThreadFactory(poolTag + "-destroyer"));
+
+        // loop for up to 10 seconds to close not used connection
+        long start = System.nanoTime();
+        do {
+          closeAll(idleConnections);
+          if (totalConnection.get() > 0) {
+            Thread.sleep(0, 10_00);
+          }
+        } while (totalConnection.get() > 0
+            && TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) < 10);
+
+        // after having wait for 10 seconds, force removal, even if used connections
+        if (totalConnection.get() > 0 || idleConnections.isEmpty()) {
+          closeAll(idleConnections);
+        }
+
+        connectionRemover.shutdown();
+        try {
+          unRegisterJmx();
+        } catch (Exception exception) {
+          // eat
+        }
+        boolean unused = connectionRemover.awaitTermination(10, TimeUnit.SECONDS);
+      }
+    } catch (Exception e) {
+      // eat
+    }
+  }
+
+  private void closeAll(Collection<MariaDbInnerPoolConnection> collection) {
+    synchronized (collection) { // synchronized mandatory to iterate Collections.synchronizedList()
+      for (MariaDbInnerPoolConnection item : collection) {
+        collection.remove(item);
+        totalConnection.decrementAndGet();
+        silentAbortConnection(item.getConnection());
+      }
+    }
+  }
+
+  /**
+   * return pool tag
+   *
+   * @return pool tag
+   */
+  public String getPoolTag() {
+    return poolTag;
+  }
+
+  @Override
+  public long getActiveConnections() {
+    return totalConnection.get() - idleConnections.size();
+  }
+
+  @Override
+  public long getTotalConnections() {
+    return totalConnection.get();
+  }
+
+  @Override
+  public long getIdleConnections() {
+    return idleConnections.size();
+  }
+
+  public long getConnectionRequests() {
+    return pendingRequestNumber.get();
+  }
+
+  private void registerJmx() throws Exception {
+    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+    String jmxName = poolTag.replace(":", "_");
+    ObjectName name = new ObjectName("org.mariadb.jdbc.pool:type=" + jmxName);
+
+    if (!mbs.isRegistered(name)) {
+      mbs.registerMBean(this, name);
+    }
+  }
+
+  private void unRegisterJmx() throws Exception {
+    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+    String jmxName = poolTag.replace(":", "_");
+    ObjectName name = new ObjectName("org.mariadb.jdbc.pool:type=" + jmxName);
+
+    if (mbs.isRegistered(name)) {
+      mbs.unregisterMBean(name);
+    }
+  }
+
+  /**
+   * For testing purpose only.
+   *
+   * @return current thread id's
+   */
+  public List<Long> testGetConnectionIdleThreadIds() {
+    List<Long> threadIds = new ArrayList<>();
+    for (MariaDbInnerPoolConnection pooledConnection : idleConnections) {
+      threadIds.add(pooledConnection.getConnection().getThreadId());
+    }
+    return threadIds;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/pool/PoolMBean.java b/src/main/java/org/mariadb/jdbc/pool/PoolMBean.java
new file mode 100644
index 0000000..5114e5c
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/pool/PoolMBean.java
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.pool;
+
+/** JMX pool bean */
+public interface PoolMBean {
+
+  /**
+   * get pool active connection number
+   *
+   * @return pool active connection number
+   */
+  long getActiveConnections();
+
+  /**
+   * get pool total connection
+   *
+   * @return pool total connection number
+   */
+  long getTotalConnections();
+
+  /**
+   * get idle connection number
+   *
+   * @return idle connection number
+   */
+  long getIdleConnections();
+
+  /**
+   * get connection waiting request number
+   *
+   * @return request number
+   */
+  long getConnectionRequests();
+}
diff --git a/src/main/java/org/mariadb/jdbc/pool/PoolThreadFactory.java b/src/main/java/org/mariadb/jdbc/pool/PoolThreadFactory.java
new file mode 100644
index 0000000..910c67d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/pool/PoolThreadFactory.java
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.pool;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/** Pool thread factory */
+public class PoolThreadFactory implements java.util.concurrent.ThreadFactory {
+
+  // start from DefaultThread factory to get security groups and what not
+  private final java.util.concurrent.ThreadFactory parentFactory = Executors.defaultThreadFactory();
+  private final AtomicInteger threadId = new AtomicInteger();
+  private final String threadName;
+
+  /**
+   * Constructor
+   *
+   * @param threadName thread name
+   */
+  public PoolThreadFactory(String threadName) {
+    this.threadName = threadName;
+  }
+
+  @Override
+  public Thread newThread(Runnable runnable) {
+    Thread result = parentFactory.newThread(runnable);
+    result.setName(threadName + "-" + threadId.incrementAndGet());
+    result.setDaemon(true); // set as daemon so that mariaDb won't hold up shutdown
+
+    return result;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/pool/Pools.java b/src/main/java/org/mariadb/jdbc/pool/Pools.java
new file mode 100644
index 0000000..809e516
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/pool/Pools.java
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.pool;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.mariadb.jdbc.Configuration;
+
+/** Pools */
+public final class Pools {
+
+  private static final AtomicInteger poolIndex = new AtomicInteger();
+  private static final Map<Configuration, Pool> poolMap = new ConcurrentHashMap<>();
+  private static ScheduledThreadPoolExecutor poolExecutor = null;
+
+  /**
+   * Get existing pool for a configuration. Create it if it doesn't exist.
+   *
+   * @param conf configuration parser
+   * @return pool
+   */
+  public static Pool retrievePool(Configuration conf) {
+    if (!poolMap.containsKey(conf)) {
+      synchronized (poolMap) {
+        if (!poolMap.containsKey(conf)) {
+          if (poolExecutor == null) {
+            poolExecutor =
+                new ScheduledThreadPoolExecutor(
+                    1, new PoolThreadFactory("MariaDbPool-maxTimeoutIdle-checker"));
+          }
+          Pool pool = new Pool(conf, poolIndex.incrementAndGet(), poolExecutor);
+          poolMap.put(conf, pool);
+          return pool;
+        }
+      }
+    }
+    return poolMap.get(conf);
+  }
+
+  /**
+   * Remove pool.
+   *
+   * @param pool pool to remove
+   */
+  public static void remove(Pool pool) {
+    if (poolMap.containsKey(pool.getConf())) {
+      synchronized (poolMap) {
+        if (poolMap.containsKey(pool.getConf())) {
+          poolMap.remove(pool.getConf());
+
+          if (poolMap.isEmpty()) {
+            shutdownExecutor();
+          }
+        }
+      }
+    }
+  }
+
+  /** Close all pools. */
+  public static void close() {
+    synchronized (poolMap) {
+      for (Pool pool : poolMap.values()) {
+        try {
+          pool.close();
+        } catch (Exception exception) {
+          // eat
+        }
+      }
+      shutdownExecutor();
+      poolMap.clear();
+    }
+  }
+
+  /**
+   * Closing a pool with name defined in url.
+   *
+   * @param poolName the option "poolName" value
+   */
+  public static void close(String poolName) {
+    if (poolName == null) {
+      return;
+    }
+    synchronized (poolMap) {
+      for (Pool pool : poolMap.values()) {
+        if (poolName.equals(pool.getConf().poolName())) {
+          try {
+            pool.close(); // Pool.close() calls Pools.remove(), which does the rest of the cleanup
+          } catch (Exception exception) {
+            // eat
+          }
+          return;
+        }
+      }
+    }
+  }
+
+  private static void shutdownExecutor() {
+    if (poolExecutor != null) {
+      poolExecutor.shutdown();
+      try {
+        poolExecutor.awaitTermination(10, TimeUnit.SECONDS);
+      } catch (InterruptedException interrupted) {
+        // eat
+      }
+      poolExecutor = null;
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/Geometry.java b/src/main/java/org/mariadb/jdbc/type/Geometry.java
new file mode 100644
index 0000000..0cd27df
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/Geometry.java
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.sql.SQLDataException;
+import org.mariadb.jdbc.client.Column;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+
+/** Geometry parser */
+public interface Geometry {
+
+  /**
+   * Parse point from packet
+   *
+   * @param littleEndian encoding order
+   * @param buf packet buffer
+   * @return point value
+   */
+  static Point parsePoint(boolean littleEndian, ReadableByteBuf buf) {
+    double x = littleEndian ? buf.readDouble() : buf.readDoubleBE();
+    double y = littleEndian ? buf.readDouble() : buf.readDoubleBE();
+    return new Point(x, y);
+  }
+
+  /**
+   * parse geometry object
+   *
+   * @param buf packet buffer
+   * @param length data length
+   * @param column column meta
+   * @return geometry parsed object
+   * @throws SQLDataException if parsing exception occurs
+   */
+  static Geometry getGeometry(ReadableByteBuf buf, int length, Column column)
+      throws SQLDataException {
+    if (length == 0) return null;
+    boolean littleEndian = buf.readByte() == 0x01;
+    int dataType = littleEndian ? buf.readInt() : buf.readIntBE();
+    switch (dataType) {
+      case 1:
+        // wkbPoint
+        return parsePoint(littleEndian, buf);
+
+      case 2:
+        // wkbLineString
+        int pointNumber = littleEndian ? buf.readInt() : buf.readIntBE();
+        Point[] points = new Point[pointNumber];
+        for (int i = 0; i < pointNumber; i++) {
+          points[i] = parsePoint(littleEndian, buf);
+        }
+        return new LineString(points, true);
+
+      case 3:
+        // wkbPolygon
+        int numRings = littleEndian ? buf.readInt() : buf.readIntBE();
+        LineString[] lines = new LineString[numRings];
+        for (int i = 0; i < numRings; i++) {
+          int pointNb = littleEndian ? buf.readInt() : buf.readIntBE();
+          Point[] lsPoints = new Point[pointNb];
+          for (int j = 0; j < pointNb; j++) {
+            lsPoints[j] = parsePoint(littleEndian, buf);
+          }
+          lines[i] = new LineString(lsPoints, false);
+        }
+        return new Polygon(lines);
+
+      case 4:
+        // wkbMultiPoint
+        int pointNb = littleEndian ? buf.readInt() : buf.readIntBE();
+        Point[] pointArr = new Point[pointNb];
+        for (int i = 0; i < pointNb; i++) {
+          pointArr[i] = (Point) getGeometry(buf, length, column);
+        }
+        return new MultiPoint(pointArr);
+
+      case 5:
+        // wkbMultiLinestring
+        int multiNb = littleEndian ? buf.readInt() : buf.readIntBE();
+        LineString[] multiLines = new LineString[multiNb];
+        for (int i = 0; i < multiNb; i++) {
+          multiLines[i] = (LineString) getGeometry(buf, length, column);
+        }
+        return new MultiLineString(multiLines);
+
+      case 6:
+        // wkbMultiPolygon
+        int multiPolyNb = littleEndian ? buf.readInt() : buf.readIntBE();
+        Polygon[] multiPolygons = new Polygon[multiPolyNb];
+        for (int i = 0; i < multiPolyNb; i++) {
+          multiPolygons[i] = (Polygon) getGeometry(buf, length, column);
+        }
+        return new MultiPolygon(multiPolygons);
+
+      case 7:
+        // wkbGeometryCollection
+        int multiCollNb = littleEndian ? buf.readInt() : buf.readIntBE();
+        Geometry[] multiGeos = new Geometry[multiCollNb];
+        for (int i = 0; i < multiCollNb; i++) {
+          multiGeos[i] = getGeometry(buf, length, column);
+        }
+        return new GeometryCollection(multiGeos);
+
+      default:
+        // ERROR
+        buf.skip(length - 5);
+        throw new SQLDataException(
+            String.format("Data type %s cannot be decoded as Geometry", column.getType()));
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/GeometryCollection.java b/src/main/java/org/mariadb/jdbc/type/GeometryCollection.java
new file mode 100644
index 0000000..af70ffa
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/GeometryCollection.java
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.util.Arrays;
+
+/** Geometry collection implementation */
+public class GeometryCollection implements Geometry {
+
+  private final Geometry[] geometries;
+
+  /**
+   * Constructor
+   *
+   * @param geometries geometry array
+   */
+  public GeometryCollection(Geometry[] geometries) {
+    this.geometries = geometries;
+  }
+
+  /**
+   * Get objects
+   *
+   * @return geometry array
+   */
+  public Geometry[] getGeometries() {
+    return geometries;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("GEOMETRYCOLLECTION(");
+    int indexpoly = 0;
+    for (Geometry geo : geometries) {
+      if (indexpoly++ > 0) {
+        sb.append(",");
+      }
+      sb.append(geo.toString());
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || !(o instanceof GeometryCollection)) return false;
+    return toString().equals(o.toString());
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(geometries);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/LineString.java b/src/main/java/org/mariadb/jdbc/type/LineString.java
new file mode 100644
index 0000000..9a4c170
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/LineString.java
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/** Linestring object */
+public class LineString implements Geometry {
+
+  private final Point[] points;
+  private final boolean open;
+
+  /**
+   * Constructor
+   *
+   * @param points point list
+   * @param open open linestring
+   */
+  public LineString(Point[] points, boolean open) {
+    this.points = points;
+    this.open = open;
+  }
+
+  /**
+   * get points
+   *
+   * @return points
+   */
+  public Point[] getPoints() {
+    return points;
+  }
+
+  /**
+   * Is form open
+   *
+   * @return is open
+   */
+  public boolean isOpen() {
+    return open;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("LINESTRING(");
+    int index = 0;
+    for (Point pt : points) {
+      if (index++ > 0) {
+        sb.append(",");
+      }
+      sb.append(pt.getX()).append(" ").append(pt.getY());
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || !(o instanceof LineString)) return false;
+    return open == ((LineString) o).isOpen() && toString().equals(o.toString());
+  }
+
+  @Override
+  public int hashCode() {
+    int result = Objects.hash(open);
+    result = 31 * result + Arrays.hashCode(points);
+    return result;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/MultiLineString.java b/src/main/java/org/mariadb/jdbc/type/MultiLineString.java
new file mode 100644
index 0000000..5bdd5f1
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/MultiLineString.java
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.util.Arrays;
+
+/** Multiline */
+public class MultiLineString implements Geometry {
+
+  private final LineString[] lines;
+
+  /**
+   * Constructor
+   *
+   * @param lines lines
+   */
+  public MultiLineString(LineString[] lines) {
+    this.lines = lines;
+  }
+
+  /**
+   * get lines
+   *
+   * @return lines
+   */
+  public LineString[] getLines() {
+    return lines;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("MULTILINESTRING(");
+    int indexLine = 0;
+    for (LineString ls : lines) {
+      if (indexLine++ > 0) {
+        sb.append(",");
+      }
+      sb.append("(");
+      int index = 0;
+      for (Point pt : ls.getPoints()) {
+        if (index++ > 0) {
+          sb.append(",");
+        }
+        sb.append(pt.getX()).append(" ").append(pt.getY());
+      }
+      sb.append(")");
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || !(o instanceof MultiLineString)) return false;
+    return toString().equals(o.toString());
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(lines);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/MultiPoint.java b/src/main/java/org/mariadb/jdbc/type/MultiPoint.java
new file mode 100644
index 0000000..2795380
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/MultiPoint.java
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.util.Arrays;
+
+/** Multi-point */
+public class MultiPoint implements Geometry {
+
+  private final Point[] points;
+
+  /**
+   * Constructor
+   *
+   * @param points points
+   */
+  public MultiPoint(Point[] points) {
+    this.points = points;
+  }
+
+  /**
+   * Get points
+   *
+   * @return points
+   */
+  public Point[] getPoints() {
+    return points;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("MULTIPOINT(");
+    int index = 0;
+    for (Point pt : points) {
+      if (index++ > 0) {
+        sb.append(",");
+      }
+      sb.append(pt.getX()).append(" ").append(pt.getY());
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || !(o instanceof MultiPoint)) return false;
+    return toString().equals(o.toString());
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(points);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/MultiPolygon.java b/src/main/java/org/mariadb/jdbc/type/MultiPolygon.java
new file mode 100644
index 0000000..e5cd799
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/MultiPolygon.java
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.util.Arrays;
+
+/** Multi polygon */
+public class MultiPolygon implements Geometry {
+
+  private final Polygon[] polygons;
+
+  /**
+   * Constructor
+   *
+   * @param polygons polygons
+   */
+  public MultiPolygon(Polygon[] polygons) {
+    this.polygons = polygons;
+  }
+
+  /**
+   * Get polygons
+   *
+   * @return polygons
+   */
+  public Polygon[] getPolygons() {
+    return polygons;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("MULTIPOLYGON(");
+    int indexpoly = 0;
+    for (Polygon poly : polygons) {
+      if (indexpoly++ > 0) {
+        sb.append(",");
+      }
+      sb.append("(");
+      int indexLine = 0;
+      for (LineString ls : poly.getLines()) {
+        if (indexLine++ > 0) {
+          sb.append(",");
+        }
+        sb.append("(");
+        int index = 0;
+        for (Point pt : ls.getPoints()) {
+          if (index++ > 0) {
+            sb.append(",");
+          }
+          sb.append(pt.getX()).append(" ").append(pt.getY());
+        }
+        sb.append(")");
+      }
+      sb.append(")");
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || !(o instanceof MultiPolygon)) return false;
+    return toString().equals(o.toString());
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(polygons);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/Point.java b/src/main/java/org/mariadb/jdbc/type/Point.java
new file mode 100644
index 0000000..ae0e062
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/Point.java
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.util.Objects;
+
+/** Point */
+public class Point implements Geometry {
+
+  private final double x;
+  private final double y;
+
+  /**
+   * Constructor
+   *
+   * @param x abscissa
+   * @param y ordinate
+   */
+  public Point(double x, double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  /**
+   * Get abscissa
+   *
+   * @return abscissa
+   */
+  public double getX() {
+    return x;
+  }
+
+  /**
+   * get ordinate
+   *
+   * @return ordinate
+   */
+  public double getY() {
+    return y;
+  }
+
+  @Override
+  public String toString() {
+    return "POINT(" + x + " " + y + ")";
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || !(o instanceof Point)) return false;
+    return toString().equals(o.toString());
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(x, y);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/type/Polygon.java b/src/main/java/org/mariadb/jdbc/type/Polygon.java
new file mode 100644
index 0000000..738c39d
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/type/Polygon.java
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.type;
+
+import java.util.Arrays;
+
+/** Polygon */
+public class Polygon implements Geometry {
+
+  private final LineString[] lines;
+
+  /**
+   * polygon
+   *
+   * @param lines lines
+   */
+  public Polygon(LineString[] lines) {
+    this.lines = lines;
+  }
+
+  /**
+   * get lines
+   *
+   * @return lines
+   */
+  public LineString[] getLines() {
+    return lines;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("POLYGON(");
+    int indexLine = 0;
+    for (LineString ls : lines) {
+      if (indexLine++ > 0) {
+        sb.append(",");
+      }
+      sb.append("(");
+      int index = 0;
+      for (Point pt : ls.getPoints()) {
+        if (index++ > 0) {
+          sb.append(",");
+        }
+        sb.append(pt.getX()).append(" ").append(pt.getY());
+      }
+      sb.append(")");
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || !(o instanceof Polygon)) return false;
+    return toString().equals(o.toString());
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(lines);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/CharsetEncodingLength.java b/src/main/java/org/mariadb/jdbc/util/CharsetEncodingLength.java
new file mode 100644
index 0000000..033024a
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/CharsetEncodingLength.java
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public final class CharsetEncodingLength {
+
+  // This array stored character length for every collation
+  // query to generate:
+  //   select  id, maxlen
+  //   from information_schema.character_sets, information_schema.collations
+  //   where character_sets.character_set_name = collations.character_set_name
+  //   order by id
+  public static final Map<Integer, Integer> maxCharlen;
+
+  static {
+    maxCharlen = new HashMap<>();
+    maxCharlen.put(1, 2);
+    maxCharlen.put(2, 1);
+    maxCharlen.put(3, 1);
+    maxCharlen.put(4, 1);
+    maxCharlen.put(5, 1);
+    maxCharlen.put(6, 1);
+    maxCharlen.put(7, 1);
+    maxCharlen.put(8, 1);
+    maxCharlen.put(9, 1);
+    maxCharlen.put(10, 1);
+    maxCharlen.put(11, 1);
+    maxCharlen.put(12, 3);
+    maxCharlen.put(13, 2);
+    maxCharlen.put(14, 1);
+    maxCharlen.put(15, 1);
+    maxCharlen.put(16, 1);
+    maxCharlen.put(18, 1);
+    maxCharlen.put(19, 2);
+    maxCharlen.put(20, 1);
+    maxCharlen.put(21, 1);
+    maxCharlen.put(22, 1);
+    maxCharlen.put(23, 1);
+    maxCharlen.put(24, 2);
+    maxCharlen.put(25, 1);
+    maxCharlen.put(26, 1);
+    maxCharlen.put(27, 1);
+    maxCharlen.put(28, 2);
+    maxCharlen.put(29, 1);
+    maxCharlen.put(30, 1);
+    maxCharlen.put(31, 1);
+    maxCharlen.put(32, 1);
+    maxCharlen.put(33, 3);
+    maxCharlen.put(34, 1);
+    maxCharlen.put(35, 2);
+    maxCharlen.put(36, 1);
+    maxCharlen.put(37, 1);
+    maxCharlen.put(38, 1);
+    maxCharlen.put(39, 1);
+    maxCharlen.put(40, 1);
+    maxCharlen.put(41, 1);
+    maxCharlen.put(42, 1);
+    maxCharlen.put(43, 1);
+    maxCharlen.put(44, 1);
+    maxCharlen.put(45, 4);
+    maxCharlen.put(46, 4);
+    maxCharlen.put(47, 1);
+    maxCharlen.put(48, 1);
+    maxCharlen.put(49, 1);
+    maxCharlen.put(50, 1);
+    maxCharlen.put(51, 1);
+    maxCharlen.put(52, 1);
+    maxCharlen.put(53, 1);
+    maxCharlen.put(54, 4);
+    maxCharlen.put(55, 4);
+    maxCharlen.put(56, 4);
+    maxCharlen.put(57, 1);
+    maxCharlen.put(58, 1);
+    maxCharlen.put(59, 1);
+    maxCharlen.put(60, 4);
+    maxCharlen.put(61, 4);
+    maxCharlen.put(62, 4);
+    maxCharlen.put(63, 1);
+    maxCharlen.put(64, 1);
+    maxCharlen.put(65, 1);
+    maxCharlen.put(66, 1);
+    maxCharlen.put(67, 1);
+    maxCharlen.put(68, 1);
+    maxCharlen.put(69, 1);
+    maxCharlen.put(70, 1);
+    maxCharlen.put(71, 1);
+    maxCharlen.put(72, 1);
+    maxCharlen.put(73, 1);
+    maxCharlen.put(74, 1);
+    maxCharlen.put(75, 1);
+    maxCharlen.put(77, 1);
+    maxCharlen.put(78, 1);
+    maxCharlen.put(79, 1);
+    maxCharlen.put(80, 1);
+    maxCharlen.put(81, 1);
+    maxCharlen.put(82, 1);
+    maxCharlen.put(83, 3);
+    maxCharlen.put(84, 2);
+    maxCharlen.put(85, 2);
+    maxCharlen.put(86, 2);
+    maxCharlen.put(87, 2);
+    maxCharlen.put(88, 2);
+    maxCharlen.put(89, 1);
+    maxCharlen.put(90, 2);
+    maxCharlen.put(91, 3);
+    maxCharlen.put(92, 1);
+    maxCharlen.put(93, 1);
+    maxCharlen.put(94, 1);
+    maxCharlen.put(95, 2);
+    maxCharlen.put(96, 2);
+    maxCharlen.put(97, 3);
+    maxCharlen.put(98, 3);
+    maxCharlen.put(99, 1);
+    maxCharlen.put(101, 4);
+    maxCharlen.put(102, 4);
+    maxCharlen.put(103, 4);
+    maxCharlen.put(104, 4);
+    maxCharlen.put(105, 4);
+    maxCharlen.put(106, 4);
+    maxCharlen.put(107, 4);
+    maxCharlen.put(108, 4);
+    maxCharlen.put(109, 4);
+    maxCharlen.put(110, 4);
+    maxCharlen.put(111, 4);
+    maxCharlen.put(112, 4);
+    maxCharlen.put(113, 4);
+    maxCharlen.put(114, 4);
+    maxCharlen.put(115, 4);
+    maxCharlen.put(116, 4);
+    maxCharlen.put(117, 4);
+    maxCharlen.put(118, 4);
+    maxCharlen.put(119, 4);
+    maxCharlen.put(120, 4);
+    maxCharlen.put(121, 4);
+    maxCharlen.put(122, 4);
+    maxCharlen.put(123, 4);
+    maxCharlen.put(124, 4);
+    maxCharlen.put(128, 2);
+    maxCharlen.put(129, 2);
+    maxCharlen.put(130, 2);
+    maxCharlen.put(131, 2);
+    maxCharlen.put(132, 2);
+    maxCharlen.put(133, 2);
+    maxCharlen.put(134, 2);
+    maxCharlen.put(135, 2);
+    maxCharlen.put(136, 2);
+    maxCharlen.put(137, 2);
+    maxCharlen.put(138, 2);
+    maxCharlen.put(139, 2);
+    maxCharlen.put(140, 2);
+    maxCharlen.put(141, 2);
+    maxCharlen.put(142, 2);
+    maxCharlen.put(143, 2);
+    maxCharlen.put(144, 2);
+    maxCharlen.put(145, 2);
+    maxCharlen.put(146, 2);
+    maxCharlen.put(147, 2);
+    maxCharlen.put(148, 2);
+    maxCharlen.put(149, 2);
+    maxCharlen.put(150, 2);
+    maxCharlen.put(151, 2);
+    maxCharlen.put(159, 2);
+    maxCharlen.put(160, 4);
+    maxCharlen.put(161, 4);
+    maxCharlen.put(162, 4);
+    maxCharlen.put(163, 4);
+    maxCharlen.put(164, 4);
+    maxCharlen.put(165, 4);
+    maxCharlen.put(166, 4);
+    maxCharlen.put(167, 4);
+    maxCharlen.put(168, 4);
+    maxCharlen.put(169, 4);
+    maxCharlen.put(170, 4);
+    maxCharlen.put(171, 4);
+    maxCharlen.put(172, 4);
+    maxCharlen.put(173, 4);
+    maxCharlen.put(174, 4);
+    maxCharlen.put(175, 4);
+    maxCharlen.put(176, 4);
+    maxCharlen.put(177, 4);
+    maxCharlen.put(178, 4);
+    maxCharlen.put(179, 4);
+    maxCharlen.put(180, 4);
+    maxCharlen.put(181, 4);
+    maxCharlen.put(182, 4);
+    maxCharlen.put(183, 4);
+    maxCharlen.put(192, 3);
+    maxCharlen.put(193, 3);
+    maxCharlen.put(194, 3);
+    maxCharlen.put(195, 3);
+    maxCharlen.put(196, 3);
+    maxCharlen.put(197, 3);
+    maxCharlen.put(198, 3);
+    maxCharlen.put(199, 3);
+    maxCharlen.put(200, 3);
+    maxCharlen.put(201, 3);
+    maxCharlen.put(202, 3);
+    maxCharlen.put(203, 3);
+    maxCharlen.put(204, 3);
+    maxCharlen.put(205, 3);
+    maxCharlen.put(206, 3);
+    maxCharlen.put(207, 3);
+    maxCharlen.put(208, 3);
+    maxCharlen.put(209, 3);
+    maxCharlen.put(210, 3);
+    maxCharlen.put(211, 3);
+    maxCharlen.put(212, 3);
+    maxCharlen.put(213, 3);
+    maxCharlen.put(214, 3);
+    maxCharlen.put(215, 3);
+    maxCharlen.put(223, 3);
+    maxCharlen.put(224, 4);
+    maxCharlen.put(225, 4);
+    maxCharlen.put(226, 4);
+    maxCharlen.put(227, 4);
+    maxCharlen.put(228, 4);
+    maxCharlen.put(229, 4);
+    maxCharlen.put(230, 4);
+    maxCharlen.put(231, 4);
+    maxCharlen.put(232, 4);
+    maxCharlen.put(233, 4);
+    maxCharlen.put(234, 4);
+    maxCharlen.put(235, 4);
+    maxCharlen.put(236, 4);
+    maxCharlen.put(237, 4);
+    maxCharlen.put(238, 4);
+    maxCharlen.put(239, 4);
+    maxCharlen.put(240, 4);
+    maxCharlen.put(241, 4);
+    maxCharlen.put(242, 4);
+    maxCharlen.put(243, 4);
+    maxCharlen.put(244, 4);
+    maxCharlen.put(245, 4);
+    maxCharlen.put(246, 4);
+    maxCharlen.put(247, 4);
+    maxCharlen.put(576, 3);
+    maxCharlen.put(577, 3);
+    maxCharlen.put(578, 3);
+    maxCharlen.put(608, 4);
+    maxCharlen.put(609, 4);
+    maxCharlen.put(610, 4);
+    maxCharlen.put(640, 2);
+    maxCharlen.put(641, 2);
+    maxCharlen.put(642, 2);
+    maxCharlen.put(672, 4);
+    maxCharlen.put(673, 4);
+    maxCharlen.put(674, 4);
+    maxCharlen.put(736, 4);
+    maxCharlen.put(737, 4);
+    maxCharlen.put(738, 4);
+    maxCharlen.put(1025, 2);
+    maxCharlen.put(1027, 1);
+    maxCharlen.put(1028, 1);
+    maxCharlen.put(1030, 1);
+    maxCharlen.put(1031, 1);
+    maxCharlen.put(1032, 1);
+    maxCharlen.put(1033, 1);
+    maxCharlen.put(1034, 1);
+    maxCharlen.put(1035, 1);
+    maxCharlen.put(1036, 3);
+    maxCharlen.put(1037, 2);
+    maxCharlen.put(1040, 1);
+    maxCharlen.put(1042, 1);
+    maxCharlen.put(1043, 2);
+    maxCharlen.put(1046, 1);
+    maxCharlen.put(1048, 2);
+    maxCharlen.put(1049, 1);
+    maxCharlen.put(1050, 1);
+    maxCharlen.put(1052, 2);
+    maxCharlen.put(1054, 1);
+    maxCharlen.put(1056, 1);
+    maxCharlen.put(1057, 3);
+    maxCharlen.put(1059, 2);
+    maxCharlen.put(1060, 1);
+    maxCharlen.put(1061, 1);
+    maxCharlen.put(1062, 1);
+    maxCharlen.put(1063, 1);
+    maxCharlen.put(1064, 1);
+    maxCharlen.put(1065, 1);
+    maxCharlen.put(1067, 1);
+    maxCharlen.put(1069, 4);
+    maxCharlen.put(1070, 4);
+    maxCharlen.put(1071, 1);
+    maxCharlen.put(1074, 1);
+    maxCharlen.put(1075, 1);
+    maxCharlen.put(1077, 1);
+    maxCharlen.put(1078, 4);
+    maxCharlen.put(1079, 4);
+    maxCharlen.put(1080, 4);
+    maxCharlen.put(1081, 1);
+    maxCharlen.put(1082, 1);
+    maxCharlen.put(1083, 1);
+    maxCharlen.put(1084, 4);
+    maxCharlen.put(1085, 4);
+    maxCharlen.put(1086, 4);
+    maxCharlen.put(1088, 1);
+    maxCharlen.put(1089, 1);
+    maxCharlen.put(1090, 1);
+    maxCharlen.put(1091, 1);
+    maxCharlen.put(1092, 1);
+    maxCharlen.put(1093, 1);
+    maxCharlen.put(1094, 1);
+    maxCharlen.put(1095, 1);
+    maxCharlen.put(1096, 1);
+    maxCharlen.put(1097, 1);
+    maxCharlen.put(1098, 1);
+    maxCharlen.put(1099, 1);
+    maxCharlen.put(1101, 1);
+    maxCharlen.put(1102, 1);
+    maxCharlen.put(1103, 1);
+    maxCharlen.put(1104, 1);
+    maxCharlen.put(1105, 1);
+    maxCharlen.put(1106, 1);
+    maxCharlen.put(1107, 3);
+    maxCharlen.put(1108, 2);
+    maxCharlen.put(1109, 2);
+    maxCharlen.put(1110, 2);
+    maxCharlen.put(1111, 2);
+    maxCharlen.put(1112, 2);
+    maxCharlen.put(1113, 1);
+    maxCharlen.put(1114, 2);
+    maxCharlen.put(1115, 3);
+    maxCharlen.put(1116, 1);
+    maxCharlen.put(1117, 1);
+    maxCharlen.put(1119, 2);
+    maxCharlen.put(1120, 2);
+    maxCharlen.put(1121, 3);
+    maxCharlen.put(1122, 3);
+    maxCharlen.put(1125, 4);
+    maxCharlen.put(1147, 4);
+    maxCharlen.put(1152, 2);
+    maxCharlen.put(1174, 2);
+    maxCharlen.put(1184, 4);
+    maxCharlen.put(1206, 4);
+    maxCharlen.put(1216, 3);
+    maxCharlen.put(1238, 3);
+    maxCharlen.put(1248, 4);
+    maxCharlen.put(1270, 4);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/ClientParser.java b/src/main/java/org/mariadb/jdbc/util/ClientParser.java
new file mode 100644
index 0000000..50d2ca5
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/ClientParser.java
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class ClientParser implements PrepareResult {
+
+  private final String sql;
+  private final byte[] query;
+  private List<Integer> paramPositions;
+  private int paramCount;
+
+  private ClientParser(String sql, byte[] query, List<Integer> paramPositions) {
+    this.sql = sql;
+    this.query = query;
+    this.paramPositions = paramPositions;
+    this.paramCount = paramPositions.size();
+  }
+
+  /**
+   * Separate query in a String list and set flag isQueryMultipleRewritable. The resulting string
+   * list is separed by ? that are not in comments. isQueryMultipleRewritable flag is set if query
+   * can be rewrite in one query (all case but if using "-- comment"). example for query : "INSERT
+   * INTO tableName(id, name) VALUES (?, ?)" result list will be : {"INSERT INTO tableName(id, name)
+   * VALUES (", ", ", ")"}
+   *
+   * @param queryString query
+   * @param noBackslashEscapes escape mode
+   * @return ClientPrepareResult
+   */
+  public static ClientParser parameterParts(String queryString, boolean noBackslashEscapes) {
+
+    List<Integer> paramPositions = new ArrayList<>();
+    LexState state = LexState.Normal;
+    byte lastChar = 0x00;
+
+    boolean singleQuotes = false;
+    byte[] query = queryString.getBytes(StandardCharsets.UTF_8);
+    int queryLength = query.length;
+    for (int i = 0; i < queryLength; i++) {
+
+      byte car = query[i];
+      if (state == LexState.Escape
+          && !((car == '\'' && singleQuotes) || (car == '"' && !singleQuotes))) {
+        state = LexState.String;
+        lastChar = car;
+        continue;
+      }
+      switch (car) {
+        case (byte) '*':
+          if (state == LexState.Normal && lastChar == (byte) '/') {
+            state = LexState.SlashStarComment;
+          }
+          break;
+
+        case (byte) '/':
+          if (state == LexState.SlashStarComment && lastChar == (byte) '*') {
+            state = LexState.Normal;
+          } else if (state == LexState.Normal && lastChar == (byte) '/') {
+            state = LexState.EOLComment;
+          }
+          break;
+
+        case (byte) '#':
+          if (state == LexState.Normal) {
+            state = LexState.EOLComment;
+          }
+          break;
+
+        case (byte) '-':
+          if (state == LexState.Normal && lastChar == (byte) '-') {
+            state = LexState.EOLComment;
+          }
+          break;
+
+        case (byte) '\n':
+          if (state == LexState.EOLComment) {
+            state = LexState.Normal;
+          }
+          break;
+
+        case (byte) '"':
+          if (state == LexState.Normal) {
+            state = LexState.String;
+            singleQuotes = false;
+          } else if (state == LexState.String && !singleQuotes) {
+            state = LexState.Normal;
+          } else if (state == LexState.Escape) {
+            state = LexState.String;
+          }
+          break;
+
+        case (byte) '\'':
+          if (state == LexState.Normal) {
+            state = LexState.String;
+            singleQuotes = true;
+          } else if (state == LexState.String && singleQuotes) {
+            state = LexState.Normal;
+          } else if (state == LexState.Escape) {
+            state = LexState.String;
+          }
+          break;
+
+        case (byte) '\\':
+          if (noBackslashEscapes) {
+            break;
+          }
+          if (state == LexState.String) {
+            state = LexState.Escape;
+          }
+          break;
+        case (byte) '?':
+          if (state == LexState.Normal) {
+            paramPositions.add(i);
+          }
+          break;
+        case (byte) '`':
+          if (state == LexState.Backtick) {
+            state = LexState.Normal;
+          } else if (state == LexState.Normal) {
+            state = LexState.Backtick;
+          }
+          break;
+      }
+      lastChar = car;
+    }
+
+    return new ClientParser(queryString, query, paramPositions);
+  }
+
+  public String getSql() {
+    return sql;
+  }
+
+  public byte[] getQuery() {
+    return query;
+  }
+
+  public List<Integer> getParamPositions() {
+    return paramPositions;
+  }
+
+  public int getParamCount() {
+    return paramCount;
+  }
+
+  enum LexState {
+    Normal, /* inside  query */
+    String, /* inside string */
+    SlashStarComment, /* inside slash-star comment */
+    Escape, /* found backslash */
+    EOLComment, /* # comment, or // comment, or -- comment */
+    Backtick /* found backtick */
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/ConfigurableSocketFactory.java b/src/main/java/org/mariadb/jdbc/util/ConfigurableSocketFactory.java
new file mode 100644
index 0000000..15507d3
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/ConfigurableSocketFactory.java
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+import javax.net.SocketFactory;
+import org.mariadb.jdbc.Configuration;
+
+public abstract class ConfigurableSocketFactory extends SocketFactory {
+  public abstract void setConfiguration(Configuration conf, String host);
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/NativeSql.java b/src/main/java/org/mariadb/jdbc/util/NativeSql.java
new file mode 100644
index 0000000..424b693
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/NativeSql.java
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+import java.sql.SQLException;
+import java.util.Locale;
+import org.mariadb.jdbc.client.Context;
+
+public final class NativeSql {
+
+  public static String parse(String sql, Context context) throws SQLException {
+    if (!sql.contains("{")) {
+      return sql;
+    }
+
+    ClientParser.LexState state = ClientParser.LexState.Normal;
+    char lastChar = '\0';
+    boolean singleQuotes = false;
+    int lastEscapePart = 0;
+
+    StringBuilder sb = new StringBuilder();
+    char[] query = sql.toCharArray();
+    int queryLength = query.length;
+    int escapeIdx = 0;
+    boolean inEscape = false;
+
+    for (int idx = 0; idx < queryLength; idx++) {
+
+      char car = query[idx];
+      if (state == ClientParser.LexState.Escape
+          && !((car == '\'' && singleQuotes) || (car == '"' && !singleQuotes))) {
+        state = ClientParser.LexState.String;
+        if (!inEscape) sb.append(car);
+        lastChar = car;
+        continue;
+      }
+      switch (car) {
+        case '*':
+          if (state == ClientParser.LexState.Normal && lastChar == '/') {
+            state = ClientParser.LexState.SlashStarComment;
+          }
+          break;
+
+        case '/':
+          if (state == ClientParser.LexState.SlashStarComment && lastChar == '*') {
+            state = ClientParser.LexState.Normal;
+          } else if (state == ClientParser.LexState.Normal && lastChar == '/') {
+            state = ClientParser.LexState.EOLComment;
+          }
+          break;
+
+        case '#':
+          if (state == ClientParser.LexState.Normal) {
+            state = ClientParser.LexState.EOLComment;
+          }
+          break;
+
+        case '-':
+          if (state == ClientParser.LexState.Normal && lastChar == '-') {
+            state = ClientParser.LexState.EOLComment;
+          }
+          break;
+
+        case '\n':
+          if (state == ClientParser.LexState.EOLComment) {
+            state = ClientParser.LexState.Normal;
+          }
+          break;
+
+        case '"':
+          if (state == ClientParser.LexState.Normal) {
+            state = ClientParser.LexState.String;
+            singleQuotes = false;
+          } else if (state == ClientParser.LexState.String && !singleQuotes) {
+            state = ClientParser.LexState.Normal;
+          } else if (state == ClientParser.LexState.Escape) {
+            state = ClientParser.LexState.String;
+          }
+          break;
+
+        case '\'':
+          if (state == ClientParser.LexState.Normal) {
+            state = ClientParser.LexState.String;
+            singleQuotes = true;
+          } else if (state == ClientParser.LexState.String && singleQuotes) {
+            state = ClientParser.LexState.Normal;
+          } else if (state == ClientParser.LexState.Escape) {
+            state = ClientParser.LexState.String;
+          }
+          break;
+
+        case '\\':
+          if (state == ClientParser.LexState.String) {
+            state = ClientParser.LexState.Escape;
+          }
+          break;
+        case '`':
+          if (state == ClientParser.LexState.Backtick) {
+            state = ClientParser.LexState.Normal;
+          } else if (state == ClientParser.LexState.Normal) {
+            state = ClientParser.LexState.Backtick;
+          }
+          break;
+        case '{':
+          if (state == ClientParser.LexState.Normal) {
+            if (!inEscape) {
+              inEscape = true;
+              lastEscapePart = idx;
+            }
+            escapeIdx++;
+          }
+          break;
+
+        case '}':
+          if (state == ClientParser.LexState.Normal) {
+            if (inEscape) {
+              escapeIdx--;
+
+              if (escapeIdx == 0) {
+                String str = sql.substring(lastEscapePart, idx + 1);
+                String escapedSeq = resolveEscapes(str, context);
+                sb.append(escapedSeq);
+                inEscape = false;
+                continue;
+              }
+            }
+          }
+          break;
+      }
+      if (!inEscape) sb.append(car);
+      lastChar = car;
+    }
+    if (inEscape) {
+      throw new SQLException(
+          "Invalid escape sequence , missing closing '}' character in '" + sql + "'");
+    }
+    return sb.toString();
+  }
+
+  private static String resolveEscapes(String escaped, Context context) throws SQLException {
+    int endIndex = escaped.length() - 1;
+    String escapedLower = escaped.toLowerCase(Locale.ROOT);
+    if (escaped.startsWith("{fn ")) {
+      String resolvedParams = replaceFunctionParameter(escaped.substring(4, endIndex), context);
+      return parse(resolvedParams, context);
+    } else if (escapedLower.startsWith("{oj ")) {
+      // Outer join
+      // the server supports "oj" in any case, even "oJ"
+      return parse(escaped.substring(4, endIndex), context);
+    } else if (escaped.startsWith("{d ")) {
+      // date literal
+      return escaped.substring(3, endIndex);
+    } else if (escaped.startsWith("{t ")) {
+      // time literal
+      return escaped.substring(3, endIndex);
+    } else if (escaped.startsWith("{ts ")) {
+      // timestamp literal
+      return escaped.substring(4, endIndex);
+    } else if (escaped.startsWith("{d'")) {
+      // date literal, no space
+      return escaped.substring(2, endIndex);
+    } else if (escaped.startsWith("{t'")) {
+      // time literal
+      return escaped.substring(2, endIndex);
+    } else if (escaped.startsWith("{ts'")) {
+      // timestamp literal
+      return escaped.substring(3, endIndex);
+    } else if (escaped.startsWith("{call ") || escaped.startsWith("{CALL ")) {
+      // We support uppercase "{CALL" only because Connector/J supports it. It is not in the JDBC
+      // spec.
+
+      return parse(escaped.substring(1, endIndex), context);
+    } else if (escaped.startsWith("{escape ")) {
+      return escaped.substring(1, endIndex);
+    } else if (escaped.startsWith("{?")) {
+      // likely ?=call(...)
+      return parse(escaped.substring(1, endIndex), context);
+    } else if (escaped.startsWith("{ ") || escaped.startsWith("{\n")) {
+      // Spaces and newlines before keyword, this is not JDBC compliant, however some it works in
+      // some drivers,
+      // so we support it, too
+      for (int i = 2; i < escaped.length(); i++) {
+        if (!Character.isWhitespace(escaped.charAt(i))) {
+          return resolveEscapes("{" + escaped.substring(i), context);
+        }
+      }
+    } else if (escaped.startsWith("{\r\n")) {
+      // Spaces and newlines before keyword, this is not JDBC compliant, however some it works in
+      // some drivers,
+      // so we support it, too
+      for (int i = 3; i < escaped.length(); i++) {
+        if (!Character.isWhitespace(escaped.charAt(i))) {
+          return resolveEscapes("{" + escaped.substring(i), context);
+        }
+      }
+    }
+    throw new SQLException("unknown escape sequence " + escaped);
+  }
+
+  /**
+   * Helper function to replace function parameters in escaped string. 3 functions are handles :
+   *
+   * <ul>
+   *   <li>CONVERT(value, type): replacing SQL_XXX types to convertible type, i.e SQL_BIGINT to
+   *       INTEGER
+   *   <li>TIMESTAMPDIFF(type, ...): replacing type SQL_TSI_XXX in type with XXX, i.e SQL_TSI_HOUR
+   *       with HOUR
+   *   <li>TIMESTAMPADD(type, ...): replacing type SQL_TSI_XXX in type with XXX, i.e SQL_TSI_HOUR
+   *       with HOUR
+   * </ul>
+   *
+   * <p>caution: this use MariaDB server conversion: 'SELECT CONVERT('2147483648', INTEGER)' will
+   * return a BIGINT. MySQL will throw a syntax error.
+   *
+   * @param functionString input string
+   * @return unescaped string
+   */
+  private static String replaceFunctionParameter(String functionString, Context context) {
+
+    char[] input = functionString.toCharArray();
+    StringBuilder sb = new StringBuilder();
+    int index;
+    for (index = 0; index < input.length; index++) {
+      if (input[index] != ' ') {
+        break;
+      }
+    }
+
+    for (;
+        index < input.length
+            && ((input[index] >= 'a' && input[index] <= 'z')
+                || (input[index] >= 'A' && input[index] <= 'Z'));
+        index++) {
+      sb.append(input[index]);
+    }
+    String func = sb.toString().toLowerCase(Locale.ROOT);
+    switch (func) {
+      case "convert":
+        // Handle "convert(value, type)" case
+        // extract last parameter, after the last ','
+        int lastCommaIndex = functionString.lastIndexOf(',');
+        int firstParentheses = functionString.indexOf('(');
+        String value = functionString.substring(firstParentheses + 1, lastCommaIndex);
+        for (index = lastCommaIndex + 1; index < input.length; index++) {
+          if (!Character.isWhitespace(input[index])) {
+            break;
+          }
+        }
+
+        int endParam = index + 1;
+        for (; endParam < input.length; endParam++) {
+          if ((input[endParam] < 'a' || input[endParam] > 'z')
+              && (input[endParam] < 'A' || input[endParam] > 'Z')
+              && input[endParam] != '_') {
+            break;
+          }
+        }
+        String typeParam = new String(input, index, endParam - index).toUpperCase(Locale.ROOT);
+        if (typeParam.startsWith("SQL_")) {
+          typeParam = typeParam.substring(4);
+        }
+
+        switch (typeParam) {
+          case "BOOLEAN":
+            return "1=" + value;
+
+          case "BIGINT":
+          case "SMALLINT":
+          case "TINYINT":
+            typeParam = "SIGNED INTEGER";
+            break;
+
+          case "BIT":
+            typeParam = "UNSIGNED INTEGER";
+            break;
+
+          case "BLOB":
+          case "VARBINARY":
+          case "LONGVARBINARY":
+          case "ROWID":
+            typeParam = "BINARY";
+            break;
+
+          case "NCHAR":
+          case "CLOB":
+          case "NCLOB":
+          case "DATALINK":
+          case "VARCHAR":
+          case "NVARCHAR":
+          case "LONGVARCHAR":
+          case "LONGNVARCHAR":
+          case "SQLXML":
+          case "LONGNCHAR":
+            typeParam = "CHAR";
+            break;
+
+          case "DOUBLE":
+          case "FLOAT":
+            if (context.getVersion().isMariaDBServer()
+                || context.getVersion().versionGreaterOrEqual(8, 0, 17)) {
+              typeParam = "DOUBLE";
+              break;
+            }
+            return "0.0+" + value;
+
+          case "REAL":
+          case "NUMERIC":
+            typeParam = "DECIMAL";
+            break;
+
+          case "TIMESTAMP":
+            typeParam = "DATETIME";
+            break;
+
+          default:
+            break;
+        }
+        return new String(input, 0, index)
+            + typeParam
+            + new String(input, endParam, input.length - endParam);
+
+      case "timestampdiff":
+      case "timestampadd":
+        // Skip to first parameter
+        for (; index < input.length; index++) {
+          if (!Character.isWhitespace(input[index]) && input[index] != '(') {
+            break;
+          }
+        }
+        if (index < input.length - 8) {
+          String paramPrefix = new String(input, index, 8);
+          if ("SQL_TSI_".equals(paramPrefix)) {
+            return new String(input, 0, index)
+                + new String(input, index + 8, input.length - (index + 8));
+          }
+        }
+        return functionString;
+
+      default:
+        return functionString;
+    }
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/ParameterList.java b/src/main/java/org/mariadb/jdbc/util/ParameterList.java
new file mode 100644
index 0000000..6e43e07
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/ParameterList.java
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+import java.util.Arrays;
+import org.mariadb.jdbc.client.util.Parameter;
+import org.mariadb.jdbc.client.util.Parameters;
+
+public class ParameterList implements Parameters, Cloneable {
+  Parameter[] elementData;
+  int length;
+
+  public ParameterList(int defaultSize) {
+    elementData = new Parameter[defaultSize];
+    length = 0;
+  }
+
+  public ParameterList() {
+    elementData = new Parameter[10];
+    length = 0;
+  }
+
+  public Parameter get(int index) {
+    if (index >= length)
+      throw new ArrayIndexOutOfBoundsException("wrong index " + index + " length:" + length);
+    return elementData[index];
+  }
+
+  public boolean containsKey(int index) {
+    if (index >= 0 && length > index) {
+      return elementData[index] != null;
+    }
+    return false;
+  }
+
+  public void set(int index, Parameter element) {
+    if (elementData.length <= index) grow(index + 1);
+    elementData[index] = element;
+    if (index >= length) length = index + 1;
+  }
+
+  public int size() {
+    return length;
+  }
+
+  private void grow(int minLength) {
+    int currLength = elementData.length;
+    int newLength = Math.max(currLength + (currLength >> 1), minLength);
+    elementData = Arrays.copyOf(elementData, newLength);
+  }
+
+  @Override
+  public ParameterList clone() {
+    ParameterList param = new ParameterList(length);
+    if (length > 0) System.arraycopy(elementData, 0, param.elementData, 0, length);
+    param.length = length;
+    return param;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/PrepareResult.java b/src/main/java/org/mariadb/jdbc/util/PrepareResult.java
new file mode 100644
index 0000000..4c071ec
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/PrepareResult.java
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+public interface PrepareResult {
+
+  String getSql();
+
+  int getParamCount();
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/Security.java b/src/main/java/org/mariadb/jdbc/util/Security.java
new file mode 100644
index 0000000..9595aa0
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/Security.java
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+public final class Security {
+
+  /**
+   * Parse the option "sessionVariable" to ensure having no injection. semi-column not in string
+   * will be replaced by comma.
+   *
+   * @param sessionVariable option value
+   * @return parsed String
+   */
+  public static String parseSessionVariables(String sessionVariable) {
+    StringBuilder out = new StringBuilder();
+    StringBuilder sb = new StringBuilder();
+    Parse state = Parse.Normal;
+    boolean iskey = true;
+    boolean singleQuotes = true;
+    boolean first = true;
+    String key = null;
+
+    char[] chars = sessionVariable.toCharArray();
+
+    for (char car : chars) {
+
+      if (state == Parse.Escape) {
+        sb.append(car);
+        state = Parse.String;
+        continue;
+      }
+
+      switch (car) {
+        case '"':
+          if (state == Parse.Normal) {
+            state = Parse.String;
+            singleQuotes = false;
+          } else if (!singleQuotes) {
+            state = Parse.Normal;
+          }
+          break;
+
+        case '\'':
+          if (state == Parse.Normal) {
+            state = Parse.String;
+            singleQuotes = true;
+          } else if (singleQuotes) {
+            state = Parse.Normal;
+          }
+          break;
+
+        case '\\':
+          if (state == Parse.String) {
+            state = Parse.Escape;
+          }
+          break;
+
+        case ';':
+        case ',':
+          if (state == Parse.Normal) {
+            if (!iskey) {
+              if (!first) {
+                out.append(",");
+              }
+              out.append(key);
+              out.append(sb);
+              first = false;
+            } else {
+              key = sb.toString().trim();
+              if (!key.isEmpty()) {
+                if (!first) {
+                  out.append(",");
+                }
+                out.append(key);
+                first = false;
+              }
+            }
+            iskey = true;
+            key = null;
+            sb = new StringBuilder();
+            continue;
+          }
+          break;
+
+        case '=':
+          if (state == Parse.Normal && iskey) {
+            key = sb.toString().trim();
+            iskey = false;
+            sb = new StringBuilder();
+          }
+          break;
+
+        default:
+          // nothing
+      }
+
+      sb.append(car);
+    }
+
+    if (!iskey) {
+      if (!first) {
+        out.append(",");
+      }
+      out.append(key);
+      out.append(sb);
+    } else {
+      String tmpkey = sb.toString().trim();
+      if (!tmpkey.isEmpty() && !first) {
+        out.append(",");
+      }
+      out.append(tmpkey);
+    }
+    return out.toString();
+  }
+
+  private enum Parse {
+    Normal,
+    String, /* inside string */
+    Escape /* found backslash */
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/StringUtils.java b/src/main/java/org/mariadb/jdbc/util/StringUtils.java
new file mode 100644
index 0000000..d420568
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/StringUtils.java
@@ -0,0 +1,17 @@
+package org.mariadb.jdbc.util;
+
+public final class StringUtils {
+  private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
+
+  public static String byteArrayToHexString(final byte[] bytes) {
+    return (bytes != null) ? getHex(bytes) : "";
+  }
+
+  private static String getHex(final byte[] raw) {
+    final StringBuilder hex = new StringBuilder(2 * raw.length);
+    for (final byte b : raw) {
+      hex.append(hexArray[(b & 0xF0) >> 4]).append(hexArray[(b & 0x0F)]);
+    }
+    return hex.toString();
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/Version.java b/src/main/java/org/mariadb/jdbc/util/Version.java
new file mode 100644
index 0000000..38f7700
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/Version.java
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+public class Version {
+  private final String version;
+  private final int majorVersion;
+  private final int minorVersion;
+  private final int patchVersion;
+  private final String qualifier;
+
+  public Version(String versionString) {
+    this.version = versionString;
+    int major = 0;
+    int minor = 0;
+    int patch = 0;
+    String qualif = "";
+
+    int length = version.length();
+    char car;
+    int offset = 0;
+    int type = 0;
+    int val = 0;
+    for (; offset < length; offset++) {
+      car = version.charAt(offset);
+      if (car < '0' || car > '9') {
+        switch (type) {
+          case 0:
+            major = val;
+            break;
+          case 1:
+            minor = val;
+            break;
+          case 2:
+            patch = val;
+            qualif = version.substring(offset);
+            offset = length;
+            break;
+          default:
+            break;
+        }
+        type++;
+        val = 0;
+      } else {
+        val = val * 10 + car - 48;
+      }
+    }
+
+    if (type == 2) {
+      patch = val;
+    }
+    this.majorVersion = major;
+    this.minorVersion = minor;
+    this.patchVersion = patch;
+    this.qualifier = qualif;
+  }
+
+  public String getVersion() {
+    return version;
+  }
+
+  public int getMajorVersion() {
+    return majorVersion;
+  }
+
+  public int getMinorVersion() {
+    return minorVersion;
+  }
+
+  public int getPatchVersion() {
+    return patchVersion;
+  }
+
+  public String getQualifier() {
+    return qualifier;
+  }
+
+  /**
+   * Utility method to check if database version is greater than parameters.
+   *
+   * @param major major version
+   * @param minor minor version
+   * @param patch patch version
+   * @return true if version is greater than parameters
+   */
+  public boolean versionGreaterOrEqual(int major, int minor, int patch) {
+    if (this.majorVersion > major) {
+      return true;
+    }
+
+    if (this.majorVersion < major) {
+      return false;
+    }
+
+    /*
+     * Major versions are equal, compare minor versions
+     */
+    if (this.minorVersion > minor) {
+      return true;
+    }
+    if (this.minorVersion < minor) {
+      return false;
+    }
+
+    // Minor versions are equal, compare patch version.
+    return this.patchVersion >= patch;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/VersionFactory.java b/src/main/java/org/mariadb/jdbc/util/VersionFactory.java
new file mode 100644
index 0000000..496ef09
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/VersionFactory.java
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public final class VersionFactory {
+  private static volatile Version instance = null;
+
+  // use getShape method to get object of type shape
+  public static Version getInstance() {
+    if (instance == null) {
+      synchronized (VersionFactory.class) {
+        if (instance == null) {
+          String tmpVersion = "5.5.0";
+          try (InputStream inputStream =
+              Version.class.getClassLoader().getResourceAsStream("mariadb.properties")) {
+            if (inputStream == null) {
+              System.out.println("property file 'mariadb.properties' not found in the classpath");
+            } else {
+              Properties prop = new Properties();
+              prop.load(inputStream);
+              tmpVersion = prop.getProperty("version");
+            }
+          } catch (IOException e) {
+            e.printStackTrace();
+          }
+          instance = new Version(tmpVersion);
+        }
+      }
+    }
+    return instance;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/constants/Capabilities.java b/src/main/java/org/mariadb/jdbc/util/constants/Capabilities.java
new file mode 100644
index 0000000..114bfa2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/constants/Capabilities.java
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.constants;
+
+/** Client / Server capabilities */
+@SuppressWarnings("unused")
+public final class Capabilities {
+
+  /** Is client mysql */
+  public static final int CLIENT_MYSQL = 1;
+
+  /** use Found rowd instead of affected rows */
+  public static final int FOUND_ROWS = 2;
+
+  /** Get all column flags */
+  public static final int LONG_FLAG = 4;
+
+  /** One can specify db on connect */
+  public static final int CONNECT_WITH_DB = 8;
+
+  /** Don't allow database.table.column */
+  public static final int NO_SCHEMA = 16;
+
+  /** use compression protocol */
+  public static final int COMPRESS = 32;
+
+  /** Odbc client */
+  public static final int ODBC = 64;
+
+  /** Can use LOAD DATA LOCAL */
+  public static final int LOCAL_FILES = 128;
+
+  /** Ignore spaces before '(' */
+  public static final int IGNORE_SPACE = 256;
+
+  /** Use 4.1 protocol */
+  public static final int CLIENT_PROTOCOL_41 = 512;
+
+  /** Is interactive client */
+  public static final int CLIENT_INTERACTIVE = 1024;
+
+  /** Switch to SSL after handshake */
+  public static final int SSL = 2048;
+
+  /** IGNORE sigpipes */
+  public static final int IGNORE_SIGPIPE = 4096;
+
+  /** transactions */
+  public static final int TRANSACTIONS = 8192;
+
+  /** reserved - not used */
+  public static final int RESERVED = 16384;
+
+  /** New 4.1 authentication */
+  public static final int SECURE_CONNECTION = 32768;
+
+  /** Enable/disable multi-stmt support */
+  public static final int MULTI_STATEMENTS = 1 << 16;
+
+  /** Enable/disable multi-results */
+  public static final int MULTI_RESULTS = 1 << 17;
+
+  /** Enable/disable multi-results for PrepareStatement */
+  public static final int PS_MULTI_RESULTS = 1 << 18;
+
+  /** Client supports plugin authentication */
+  public static final int PLUGIN_AUTH = 1 << 19;
+
+  /** Client send connection attributes */
+  public static final int CONNECT_ATTRS = 1 << 20;
+
+  /** authentication data length is a length auth integer */
+  public static final int PLUGIN_AUTH_LENENC_CLIENT_DATA = 1 << 21;
+
+  /** server send session tracking info */
+  public static final int CLIENT_SESSION_TRACK = 1 << 23;
+
+  /** EOF packet deprecated */
+  public static final int CLIENT_DEPRECATE_EOF = 1 << 24;
+
+  /** Client support progress indicator (before 10.2) */
+  public static final int PROGRESS_OLD = 1 << 29;
+
+  /* MariaDB specific capabilities */
+
+  /** Client progression */
+  public static final long PROGRESS = 1L << 32;
+
+  /** not used anymore - reserved */
+  public static final long MARIADB_RESERVED = 1L << 33;
+
+  /** permit COM_STMT_BULK commands */
+  public static final long STMT_BULK_OPERATIONS = 1L << 34;
+
+  /** metadata extended information */
+  public static final long EXTENDED_TYPE_INFO = 1L << 35;
+
+  /** permit metadata caching */
+  public static final long CACHE_METADATA = 1L << 36;
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/constants/ColumnFlags.java b/src/main/java/org/mariadb/jdbc/util/constants/ColumnFlags.java
new file mode 100644
index 0000000..7b7fad2
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/constants/ColumnFlags.java
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.constants;
+
+/** Column flag see https://mariadb.com/kb/en/result-set-packets/#field-details-flag */
+@SuppressWarnings("unused")
+public final class ColumnFlags {
+
+  /** must a column have non-null value only */
+  public static final short NOT_NULL = 1;
+
+  /** Is column a primary key */
+  public static final short PRIMARY_KEY = 2;
+
+  /** Is this column a unique key */
+  public static final short UNIQUE_KEY = 4;
+
+  /** Is this column part of a multiple column key */
+  public static final short MULTIPLE_KEY = 8;
+
+  /** Does this column contain blob */
+  public static final short BLOB = 16;
+
+  /** Is column number value unsigned */
+  public static final short UNSIGNED = 32;
+
+  /** Must number value be filled with Zero */
+  public static final short ZEROFILL = 64;
+
+  /** Is binary value */
+  public static final short BINARY_COLLATION = 128;
+
+  /** Is column of type enum */
+  public static final short ENUM = 256;
+
+  /** Does column auto-increment */
+  public static final short AUTO_INCREMENT = 512;
+
+  /** Is column of type Timestamp */
+  public static final short TIMESTAMP = 1024;
+
+  /** Is column type set */
+  public static final short SET = 2048;
+
+  /** Does column have no default value */
+  public static final short NO_DEFAULT_VALUE_FLAG = 4096;
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/constants/ConnectionState.java b/src/main/java/org/mariadb/jdbc/util/constants/ConnectionState.java
new file mode 100644
index 0000000..3544473
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/constants/ConnectionState.java
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.constants;
+
+/** Connection state change, to ensure what is needed to reset connection to a proper state */
+public final class ConnectionState {
+  /** flag indicating that network timeout has been changed */
+  public static final int STATE_NETWORK_TIMEOUT = 1;
+
+  /** flag indicating that default database has been changed */
+  public static final int STATE_DATABASE = 2;
+
+  /** flag indicating that connection read only has been changed */
+  public static final int STATE_READ_ONLY = 4;
+
+  /** flag indicating that autocommit has been changed */
+  public static final int STATE_AUTOCOMMIT = 8;
+
+  /** flag indicating that transaction isolation has been changed */
+  public static final int STATE_TRANSACTION_ISOLATION = 16;
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/constants/ServerStatus.java b/src/main/java/org/mariadb/jdbc/util/constants/ServerStatus.java
new file mode 100644
index 0000000..67976e8
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/constants/ServerStatus.java
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.constants;
+
+/** Server status flags */
+@SuppressWarnings("unused")
+public class ServerStatus {
+  /** is in transaction */
+  public static final short IN_TRANSACTION = 1;
+  /** autocommit */
+  public static final short AUTOCOMMIT = 2;
+  /** more result exists (packet follows) */
+  public static final short MORE_RESULTS_EXISTS = 8;
+  /** no good index was used */
+  public static final short QUERY_NO_GOOD_INDEX_USED = 16;
+  /** no index was used */
+  public static final short QUERY_NO_INDEX_USED = 32;
+  /** cursor exists */
+  public static final short CURSOR_EXISTS = 64;
+  /** last row sent */
+  public static final short LAST_ROW_SENT = 128;
+  /** database dropped */
+  public static final short DB_DROPPED = 256;
+  /** escape type */
+  public static final short NO_BACKSLASH_ESCAPES = 512;
+  /** metadata changed */
+  public static final short METADATA_CHANGED = 1024;
+  /** query was slow */
+  public static final short QUERY_WAS_SLOW = 2048;
+  /** resultset contains output parameters */
+  public static final short PS_OUT_PARAMETERS = 4096;
+  /** session state change (OK_Packet contains additional data) */
+  public static final short SERVER_SESSION_STATE_CHANGED = 1 << 14;
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/constants/StateChange.java b/src/main/java/org/mariadb/jdbc/util/constants/StateChange.java
new file mode 100644
index 0000000..613b750
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/constants/StateChange.java
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.constants;
+
+/** OK_PACKET state change flags */
+@SuppressWarnings("unused")
+public final class StateChange {
+  /** system variable change */
+  public static final short SESSION_TRACK_SYSTEM_VARIABLES = 0;
+  /** schema change */
+  public static final short SESSION_TRACK_SCHEMA = 1;
+  /** state change */
+  public static final short SESSION_TRACK_STATE_CHANGE = 2;
+  /** GTID change */
+  public static final short SESSION_TRACK_GTIDS = 3;
+  /** transaction characteristics change */
+  public static final short SESSION_TRACK_TRANSACTION_CHARACTERISTICS = 4;
+  /** transaction state change */
+  public static final short SESSION_TRACK_TRANSACTION_STATE = 5;
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/log/ConsoleLogger.java b/src/main/java/org/mariadb/jdbc/util/log/ConsoleLogger.java
new file mode 100644
index 0000000..75310d0
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/log/ConsoleLogger.java
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.log;
+
+import java.io.PrintStream;
+import java.util.regex.Matcher;
+
+/** Logger that will log to console */
+@SuppressWarnings("ALL")
+public class ConsoleLogger implements Logger {
+
+  private final String name;
+  private final PrintStream err;
+  private final PrintStream log;
+  private final boolean logDebugLvl;
+
+  /**
+   * Constructor. All logs will be send to console.
+   *
+   * @param name name to log
+   * @param log log stream
+   * @param err error stream
+   * @param logDebugLvl log level
+   */
+  public ConsoleLogger(String name, PrintStream log, PrintStream err, boolean logDebugLvl) {
+    this.name = name;
+    this.log = log;
+    this.err = err;
+    this.logDebugLvl = logDebugLvl;
+  }
+
+  ConsoleLogger(String name, boolean logDebugLvl) {
+    this(name, System.out, System.err, logDebugLvl);
+  }
+
+  @Override
+  public String getName() {
+    return this.name;
+  }
+
+  final String format(String from, Object... arguments) {
+    if (from != null) {
+      String computed = from;
+      for (Object argument : arguments) {
+        computed =
+            computed.replaceFirst("\\{\\}", Matcher.quoteReplacement(String.valueOf(argument)));
+      }
+      return computed;
+    }
+    return null;
+  }
+
+  @Override
+  public boolean isTraceEnabled() {
+    return logDebugLvl;
+  }
+
+  @Override
+  public synchronized void trace(String msg) {
+    if (!logDebugLvl) {
+      return;
+    }
+    this.log.format("[TRACE] (%s) %s\n", Thread.currentThread().getName(), msg);
+  }
+
+  @Override
+  public synchronized void trace(String format, Object... arguments) {
+    if (!logDebugLvl) {
+      return;
+    }
+    this.log.format(
+        "[TRACE] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
+  }
+
+  @Override
+  public synchronized void trace(String msg, Throwable t) {
+    if (!logDebugLvl) {
+      return;
+    }
+    this.log.format("[TRACE] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
+    t.printStackTrace(this.log);
+  }
+
+  @Override
+  public boolean isDebugEnabled() {
+    return logDebugLvl;
+  }
+
+  @Override
+  public synchronized void debug(String msg) {
+    if (!logDebugLvl) {
+      return;
+    }
+    this.log.format("[DEBUG] (%s) %s\n", Thread.currentThread().getName(), msg);
+  }
+
+  @Override
+  public synchronized void debug(String format, Object... arguments) {
+    if (!logDebugLvl) {
+      return;
+    }
+    this.log.format(
+        "[DEBUG] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
+  }
+
+  @Override
+  public synchronized void debug(String msg, Throwable t) {
+    if (!logDebugLvl) {
+      return;
+    }
+    this.log.format("[DEBUG] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
+    t.printStackTrace(this.log);
+  }
+
+  @Override
+  public boolean isInfoEnabled() {
+    return true;
+  }
+
+  @Override
+  public synchronized void info(String msg) {
+    this.log.format("[ INFO] (%s) %s\n", Thread.currentThread().getName(), msg);
+  }
+
+  @Override
+  public synchronized void info(String format, Object... arguments) {
+    this.log.format(
+        "[ INFO] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
+  }
+
+  @Override
+  public synchronized void info(String msg, Throwable t) {
+    this.log.format("[ INFO] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
+    t.printStackTrace(this.log);
+  }
+
+  @Override
+  public boolean isWarnEnabled() {
+    return true;
+  }
+
+  @Override
+  public synchronized void warn(String msg) {
+    this.err.format("[ WARN] (%s) %s\n", Thread.currentThread().getName(), msg);
+  }
+
+  @Override
+  public synchronized void warn(String format, Object... arguments) {
+    this.err.format(
+        "[ WARN] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
+  }
+
+  @Override
+  public synchronized void warn(String msg, Throwable t) {
+    this.err.format("[ WARN] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
+    t.printStackTrace(this.err);
+  }
+
+  @Override
+  public boolean isErrorEnabled() {
+    return true;
+  }
+
+  @Override
+  public synchronized void error(String msg) {
+    this.err.format("[ERROR] (%s) %s\n", Thread.currentThread().getName(), msg);
+  }
+
+  @Override
+  public synchronized void error(String format, Object... arguments) {
+    this.err.format(
+        "[ERROR] (%s) %s\n", Thread.currentThread().getName(), format(format, arguments));
+  }
+
+  @Override
+  public synchronized void error(String msg, Throwable t) {
+    this.err.format("[ERROR] (%s) %s - %s\n", Thread.currentThread().getName(), msg, t);
+    t.printStackTrace(this.err);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/log/JdkLogger.java b/src/main/java/org/mariadb/jdbc/util/log/JdkLogger.java
new file mode 100644
index 0000000..d06e42e
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/log/JdkLogger.java
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.log;
+
+import java.util.logging.Level;
+import java.util.regex.Matcher;
+
+/** Logger using standard java logging */
+public class JdkLogger implements Logger {
+
+  /** logger implementation */
+  private final java.util.logging.Logger logger;
+
+  /**
+   * Constructor
+   *
+   * @param logger java logger
+   */
+  public JdkLogger(java.util.logging.Logger logger) {
+    this.logger = logger;
+  }
+
+  @Override
+  public String getName() {
+    return logger.getName();
+  }
+
+  @Override
+  public boolean isTraceEnabled() {
+    return logger.isLoggable(Level.FINEST);
+  }
+
+  @Override
+  public void trace(String msg) {
+    logger.log(Level.FINEST, msg);
+  }
+
+  @Override
+  public void trace(String format, Object... arguments) {
+    logger.log(Level.FINEST, format(format, arguments));
+  }
+
+  @Override
+  public void trace(String msg, Throwable t) {
+    logger.log(Level.FINEST, msg, t);
+  }
+
+  @Override
+  public boolean isDebugEnabled() {
+    return logger.isLoggable(Level.FINE);
+  }
+
+  @Override
+  public void debug(String msg) {
+    logger.log(Level.FINE, msg);
+  }
+
+  @Override
+  public void debug(String format, Object... arguments) {
+    logger.log(Level.FINE, format(format, arguments));
+  }
+
+  @Override
+  public void debug(String msg, Throwable t) {
+    logger.log(Level.FINE, msg, t);
+  }
+
+  @Override
+  public boolean isInfoEnabled() {
+    return logger.isLoggable(Level.INFO);
+  }
+
+  @Override
+  public void info(String msg) {
+    logger.log(Level.INFO, msg);
+  }
+
+  @Override
+  public void info(String format, Object... arguments) {
+    logger.log(Level.INFO, format(format, arguments));
+  }
+
+  @Override
+  public void info(String msg, Throwable t) {
+    logger.log(Level.INFO, msg, t);
+  }
+
+  @Override
+  public boolean isWarnEnabled() {
+    return logger.isLoggable(Level.WARNING);
+  }
+
+  @Override
+  public void warn(String msg) {
+    logger.log(Level.WARNING, msg);
+  }
+
+  @Override
+  public void warn(String format, Object... arguments) {
+    logger.log(Level.WARNING, format(format, arguments));
+  }
+
+  @Override
+  public void warn(String msg, Throwable t) {
+    logger.log(Level.WARNING, msg, t);
+  }
+
+  @Override
+  public boolean isErrorEnabled() {
+    return logger.isLoggable(Level.SEVERE);
+  }
+
+  @Override
+  public void error(String msg) {
+    logger.log(Level.SEVERE, msg);
+  }
+
+  @Override
+  public void error(String format, Object... arguments) {
+    logger.log(Level.SEVERE, format(format, arguments));
+  }
+
+  @Override
+  public void error(String msg, Throwable t) {
+    logger.log(Level.SEVERE, msg, t);
+  }
+
+  final String format(String from, Object... arguments) {
+    if (from != null) {
+      String computed = from;
+      for (Object argument : arguments) {
+        computed =
+            computed.replaceFirst("\\{}", Matcher.quoteReplacement(String.valueOf(argument)));
+      }
+      return computed;
+    }
+    return null;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/log/Logger.java b/src/main/java/org/mariadb/jdbc/util/log/Logger.java
new file mode 100644
index 0000000..baa47f1
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/log/Logger.java
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.log;
+
+/** Logger interface */
+public interface Logger {
+  /**
+   * Logger name
+   *
+   * @return logger name
+   */
+  String getName();
+
+  /**
+   * Must TRACE level be logged
+   *
+   * @return if TRACE level be logger
+   */
+  boolean isTraceEnabled();
+
+  /**
+   * Log a message at the TRACE level.
+   *
+   * @param msg the message string to be logged
+   */
+  void trace(String msg);
+
+  /**
+   * Log a message at the TRACE level.
+   *
+   * @param format the format string
+   * @param arguments arguments
+   */
+  void trace(String format, Object... arguments);
+
+  /**
+   * Log a message with an error at the TRACE level.
+   *
+   * @param msg message
+   * @param t error
+   */
+  void trace(String msg, Throwable t);
+
+  /**
+   * must DEBUG level message be logged
+   *
+   * @return are DEBUG message to be logged
+   */
+  boolean isDebugEnabled();
+
+  /**
+   * Log a message at the DEBUG level.
+   *
+   * @param msg the message string to be logged
+   */
+  void debug(String msg);
+
+  /**
+   * Log a message at the DEBUG level.
+   *
+   * @param format the format string
+   * @param arguments arguments
+   */
+  void debug(String format, Object... arguments);
+
+  /**
+   * Log a message with an error at the DEBUG level.
+   *
+   * @param msg message
+   * @param t error
+   */
+  void debug(String msg, Throwable t);
+
+  /**
+   * Must INFO level be logged
+   *
+   * @return if INFO level be logger
+   */
+  boolean isInfoEnabled();
+
+  /**
+   * Log a message at the INFO level.
+   *
+   * @param msg the message string to be logged
+   */
+  void info(String msg);
+
+  /**
+   * Log a message at the INFO level.
+   *
+   * @param format the format string
+   * @param arguments arguments
+   */
+  void info(String format, Object... arguments);
+
+  /**
+   * Log a message with an error at the INFO level.
+   *
+   * @param msg message
+   * @param t error
+   */
+  void info(String msg, Throwable t);
+
+  /**
+   * Must WARN level be logged
+   *
+   * @return if WARN level be logger
+   */
+  boolean isWarnEnabled();
+
+  /**
+   * Log a message at the WARN level.
+   *
+   * @param msg the message string to be logged
+   */
+  void warn(String msg);
+
+  /**
+   * Log a message at the WARNING level.
+   *
+   * @param format the format string
+   * @param arguments arguments
+   */
+  void warn(String format, Object... arguments);
+
+  /**
+   * Log a message with an error at the WARNING level.
+   *
+   * @param msg message
+   * @param t error
+   */
+  void warn(String msg, Throwable t);
+
+  /**
+   * Must ERROR level be logged
+   *
+   * @return if ERROR level be logger
+   */
+  boolean isErrorEnabled();
+
+  /**
+   * Log a message at the ERROR level.
+   *
+   * @param msg the message string to be logged
+   */
+  void error(String msg);
+
+  /**
+   * Log a message at the ERROR level.
+   *
+   * @param format the format string
+   * @param arguments arguments
+   */
+  void error(String format, Object... arguments);
+
+  /**
+   * Log a message with an error at the ERROR level.
+   *
+   * @param msg message
+   * @param t error
+   */
+  void error(String msg, Throwable t);
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/log/LoggerHelper.java b/src/main/java/org/mariadb/jdbc/util/log/LoggerHelper.java
new file mode 100644
index 0000000..9fce199
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/log/LoggerHelper.java
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.log;
+
+/** Logger helper to display network exchange */
+public final class LoggerHelper {
+
+  private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
+
+  /**
+   * Write bytes/hexadecimal value of a byte array to a StringBuilder.
+   *
+   * <p>String output example :
+   *
+   * <pre>{@code
+   * +--------------------------------------------------+
+   * |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |
+   * +--------------------------------------------------+------------------+
+   * | 5F 00 00 00 03 73 65 74  20 61 75 74 6F 63 6F 6D | _....set autocom |
+   * | 6D 69 74 3D 31 2C 20 73  65 73 73 69 6F 6E 5F 74 | mit=1, session_t |
+   * | 72 61 63 6B 5F 73 63 68  65 6D 61 3D 31 2C 20 73 | rack_schema=1, s |
+   * | 71 6C 5F 6D 6F 64 65 20  3D 20 63 6F 6E 63 61 74 | ql_mode = concat |
+   * | 28 40 40 73 71 6C 5F 6D  6F 64 65 2C 27 2C 53 54 | (@@sql_mode,',ST |
+   * | 52 49 43 54 5F 54 52 41  4E 53 5F 54 41 42 4C 45 | RICT_TRANS_TABLE |
+   * | 53 27 29                                         | S')              |
+   * +--------------------------------------------------+------------------+
+   * }</pre>
+   *
+   * @param bytes byte array
+   * @param offset offset
+   * @param dataLength byte length to write
+   * @return formated hexa
+   */
+  public static String hex(byte[] bytes, int offset, int dataLength) {
+    return hex(bytes, offset, dataLength, Integer.MAX_VALUE);
+  }
+
+  /**
+   * Transform bytes into readable string format
+   *
+   * @param bytes bytes
+   * @param offset offset
+   * @param dataLength data length
+   * @param trunkLength truncation limit
+   * @return readable string format
+   */
+  public static String hex(byte[] bytes, int offset, int dataLength, int trunkLength) {
+
+    if (bytes == null || bytes.length == 0) {
+      return "";
+    }
+
+    char[] hexaValue = new char[16];
+    hexaValue[8] = ' ';
+
+    int pos = offset;
+    int line = 1;
+    int posHexa = 0;
+    int logLength = Math.min(dataLength, trunkLength);
+    StringBuilder sb = new StringBuilder(logLength * 3);
+    sb.append(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| ");
+
+    while (pos < logLength + offset) {
+      int byteValue = bytes[pos] & 0xFF;
+      sb.append(hexArray[byteValue >>> 4]).append(hexArray[byteValue & 0x0F]).append(" ");
+
+      hexaValue[posHexa++] = (byteValue > 31 && byteValue < 127) ? (char) byteValue : '.';
+
+      if (posHexa == 8) {
+        sb.append(" ");
+      }
+      if (posHexa == 16) {
+        sb.append("| ").append(hexaValue).append(" |\n");
+        if (pos + 1 != logLength + offset)
+          sb.append("|").append(mediumIntTohexa(line++)).append("| ");
+        posHexa = 0;
+      }
+      pos++;
+    }
+
+    int remaining = posHexa;
+    if (remaining > 0) {
+      if (remaining < 8) {
+        for (; remaining < 8; remaining++) {
+          sb.append("   ");
+        }
+        sb.append(" ");
+      }
+
+      for (; remaining < 16; remaining++) {
+        sb.append("   ");
+      }
+
+      for (; posHexa < 16; posHexa++) {
+        hexaValue[posHexa] = ' ';
+      }
+
+      sb.append("| ").append(hexaValue).append(" |\n");
+    }
+    if (dataLength > trunkLength) {
+      sb.append("+------+-------------------truncated----------------------+------------------+\n");
+    } else {
+      sb.append("+------+--------------------------------------------------+------------------+\n");
+    }
+    return sb.toString();
+  }
+
+  private static String mediumIntTohexa(int value) {
+    String st = Integer.toHexString(value * 16);
+    while (st.length() < 6) st = "0" + st;
+    return st;
+  }
+
+  /**
+   * return a string containing hexa displayable value of arrays
+   *
+   * @param header header array
+   * @param bytes data content
+   * @param offset data offset
+   * @param dataLength data length
+   * @param trunkLength data limit
+   * @return displayable value of arrays
+   */
+  public static String hex(
+      byte[] header, byte[] bytes, int offset, int dataLength, int trunkLength) {
+    byte[] complete = new byte[dataLength + header.length];
+    System.arraycopy(header, 0, complete, 0, header.length);
+    System.arraycopy(bytes, offset, complete, header.length, dataLength);
+    return hex(complete, 0, dataLength + header.length, trunkLength);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/log/Loggers.java b/src/main/java/org/mariadb/jdbc/util/log/Loggers.java
new file mode 100644
index 0000000..c1ad699
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/log/Loggers.java
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.log;
+
+import java.util.HashMap;
+
+/** Loggers factory */
+public final class Loggers {
+
+  /** defined if using JDK if sfl4j is not present. possible values: JDK/CONSOLE */
+  public static final String FALLBACK_PROPERTY = "mariadb.logging.fallback";
+
+  /** set if console must log debug level */
+  public static final String CONSOLE_DEBUG_PROPERTY = "mariadb.logging.fallback.console.debug";
+
+  /** !! testing only !! permit to disable SLF4J implementation even if SLF4j is present */
+  public static final String TEST_ENABLE_SLF4J = "mariadb.logging.slf4j.enable";
+
+  /** disable logging */
+  public static final String NO_LOGGER_PROPERTY = "mariadb.logging.disable";
+
+  /** factory */
+  private static LoggerFactory LOGGER_FACTORY;
+
+  static {
+    init();
+  }
+
+  /**
+   * Return default logger implementation
+   *
+   * @param name logger name
+   * @return logger implementation
+   */
+  public static Logger getLogger(String name) {
+    return LOGGER_FACTORY.getLogger(name);
+  }
+
+  /**
+   * Return default logger implementation
+   *
+   * @param cls class
+   * @return logger implementation
+   */
+  public static Logger getLogger(Class<?> cls) {
+    return LOGGER_FACTORY.getLogger(cls.getName());
+  }
+
+  private interface LoggerFactory {
+    Logger getLogger(String name);
+  }
+
+  private static class NoLoggerFactory implements LoggerFactory {
+    @Override
+    public Logger getLogger(String name) {
+      return new NoLogger();
+    }
+  }
+
+  private static class Slf4JLoggerFactory implements LoggerFactory {
+    @Override
+    public Logger getLogger(String name) {
+      return new Slf4JLogger(org.slf4j.LoggerFactory.getLogger(name));
+    }
+  }
+
+  /** JDK wrapper */
+  private static class JdkLoggerFactory implements LoggerFactory {
+    @Override
+    public Logger getLogger(String name) {
+      return new JdkLogger(java.util.logging.Logger.getLogger(name));
+    }
+  }
+
+  private static final class ConsoleLoggerFactory implements LoggerFactory {
+
+    private static final HashMap<String, Logger> consoleLoggers = new HashMap<>();
+
+    @Override
+    public Logger getLogger(String name) {
+      return consoleLoggers.computeIfAbsent(
+          name, n -> new ConsoleLogger(n, System.getProperty(CONSOLE_DEBUG_PROPERTY) != null));
+    }
+  }
+
+  /** Initialize factory */
+  public static void init() {
+    String name = LoggerFactory.class.getName();
+    LoggerFactory loggerFactory = null;
+    if (Boolean.parseBoolean(System.getProperty(NO_LOGGER_PROPERTY, "false"))) {
+      loggerFactory = new NoLoggerFactory();
+    } else {
+
+      try {
+        if (Boolean.parseBoolean(System.getProperty(TEST_ENABLE_SLF4J, "true"))) {
+          Class.forName("org.slf4j.LoggerFactory");
+          loggerFactory = new Slf4JLoggerFactory();
+        }
+      } catch (ClassNotFoundException cle) {
+        // slf4j not in the classpath
+      }
+      if (loggerFactory == null) {
+        // default to console or use JDK logger if explicitly set by System property
+        if ("JDK".equalsIgnoreCase(System.getProperty(FALLBACK_PROPERTY))) {
+          loggerFactory = new JdkLoggerFactory();
+        } else {
+          loggerFactory = new ConsoleLoggerFactory();
+        }
+      }
+      try {
+        loggerFactory.getLogger(name);
+      } catch (Throwable e) {
+        // eat
+      }
+    }
+    LOGGER_FACTORY = loggerFactory;
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/log/NoLogger.java b/src/main/java/org/mariadb/jdbc/util/log/NoLogger.java
new file mode 100644
index 0000000..dc80ebc
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/log/NoLogger.java
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.log;
+
+/** No logger implementation */
+public class NoLogger implements org.mariadb.jdbc.util.log.Logger {
+
+  @Override
+  public String getName() {
+    return "";
+  }
+
+  @Override
+  public boolean isTraceEnabled() {
+    return false;
+  }
+
+  @Override
+  public void trace(String msg) {}
+
+  @Override
+  public void trace(String format, Object... arguments) {}
+
+  @Override
+  public void trace(String msg, Throwable t) {}
+
+  @Override
+  public boolean isDebugEnabled() {
+    return false;
+  }
+
+  @Override
+  public void debug(String msg) {}
+
+  @Override
+  public void debug(String format, Object... arguments) {}
+
+  @Override
+  public void debug(String msg, Throwable t) {}
+
+  @Override
+  public boolean isInfoEnabled() {
+    return false;
+  }
+
+  @Override
+  public void info(String msg) {}
+
+  @Override
+  public void info(String format, Object... arguments) {}
+
+  @Override
+  public void info(String msg, Throwable t) {}
+
+  @Override
+  public boolean isWarnEnabled() {
+    return false;
+  }
+
+  @Override
+  public void warn(String msg) {}
+
+  @Override
+  public void warn(String format, Object... arguments) {}
+
+  @Override
+  public void warn(String msg, Throwable t) {}
+
+  @Override
+  public boolean isErrorEnabled() {
+    return false;
+  }
+
+  @Override
+  public void error(String msg) {}
+
+  @Override
+  public void error(String format, Object... arguments) {}
+
+  @Override
+  public void error(String msg, Throwable t) {}
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/log/Slf4JLogger.java b/src/main/java/org/mariadb/jdbc/util/log/Slf4JLogger.java
new file mode 100644
index 0000000..40fa949
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/log/Slf4JLogger.java
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.log;
+
+import org.slf4j.Logger;
+
+/** SLF4J logger wrapper */
+public class Slf4JLogger implements org.mariadb.jdbc.util.log.Logger {
+
+  private final Logger logger;
+
+  /**
+   * Constructor
+   *
+   * @param logger SLF4J logger
+   */
+  public Slf4JLogger(Logger logger) {
+    this.logger = logger;
+  }
+
+  @Override
+  public String getName() {
+    return logger.getName();
+  }
+
+  @Override
+  public boolean isTraceEnabled() {
+    return logger.isTraceEnabled();
+  }
+
+  @Override
+  public void trace(String msg) {
+    logger.trace(msg);
+  }
+
+  @Override
+  public void trace(String format, Object... arguments) {
+    logger.trace(format, arguments);
+  }
+
+  @Override
+  public void trace(String msg, Throwable t) {
+    logger.trace(msg, t);
+  }
+
+  @Override
+  public boolean isDebugEnabled() {
+    return logger.isDebugEnabled();
+  }
+
+  @Override
+  public void debug(String msg) {
+    logger.debug(msg);
+  }
+
+  @Override
+  public void debug(String format, Object... arguments) {
+    logger.debug(format, arguments);
+  }
+
+  @Override
+  public void debug(String msg, Throwable t) {
+    logger.debug(msg, t);
+  }
+
+  @Override
+  public boolean isInfoEnabled() {
+    return logger.isInfoEnabled();
+  }
+
+  @Override
+  public void info(String msg) {
+    logger.info(msg);
+  }
+
+  @Override
+  public void info(String format, Object... arguments) {
+    logger.info(format, arguments);
+  }
+
+  @Override
+  public void info(String msg, Throwable t) {
+    logger.info(msg, t);
+  }
+
+  @Override
+  public boolean isWarnEnabled() {
+    return logger.isWarnEnabled();
+  }
+
+  @Override
+  public void warn(String msg) {
+    logger.warn(msg);
+  }
+
+  @Override
+  public void warn(String format, Object... arguments) {
+    logger.warn(format, arguments);
+  }
+
+  @Override
+  public void warn(String msg, Throwable t) {
+    logger.warn(msg, t);
+  }
+
+  @Override
+  public boolean isErrorEnabled() {
+    return logger.isErrorEnabled();
+  }
+
+  @Override
+  public void error(String msg) {
+    logger.error(msg);
+  }
+
+  @Override
+  public void error(String format, Object... arguments) {
+    logger.error(format, arguments);
+  }
+
+  @Override
+  public void error(String msg, Throwable t) {
+    logger.error(msg, t);
+  }
+}
diff --git a/src/main/java/org/mariadb/jdbc/util/options/OptionAliases.java b/src/main/java/org/mariadb/jdbc/util/options/OptionAliases.java
new file mode 100644
index 0000000..78cc9b1
--- /dev/null
+++ b/src/main/java/org/mariadb/jdbc/util/options/OptionAliases.java
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.util.options;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/** Option alias name */
+public final class OptionAliases {
+
+  /** list of aliases */
+  public static final Map<String, String> OPTIONS_ALIASES;
+
+  static {
+    OPTIONS_ALIASES = new HashMap<>();
+    OPTIONS_ALIASES.put("clientcertificatekeystoreurl", "keyStore");
+    OPTIONS_ALIASES.put("clientcertificatekeystorepassword", "keyStorePassword");
+    OPTIONS_ALIASES.put("clientcertificatekeystoretype", "keyStoreType");
+  }
+}
diff --git a/src/main/java11/org/mariadb/jdbc/client/SocketHelper.java b/src/main/java11/org/mariadb/jdbc/client/SocketHelper.java
new file mode 100644
index 0000000..a26f708
--- /dev/null
+++ b/src/main/java11/org/mariadb/jdbc/client/SocketHelper.java
@@ -0,0 +1,39 @@
+package org.mariadb.jdbc.client;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import jdk.net.ExtendedSocketOptions;
+import org.mariadb.jdbc.Configuration;
+
+public class SocketHelper {
+  public static void setSocketOption(final Configuration conf, final Socket socket)
+      throws IOException {
+    socket.setTcpNoDelay(true);
+    socket.setSoTimeout(conf.socketTimeout());
+    if (conf.tcpKeepAlive()) {
+      socket.setKeepAlive(true);
+    }
+    if (conf.tcpAbortiveClose()) {
+      socket.setSoLinger(true, 0);
+    }
+
+    // java 11 only
+    if (conf.tcpKeepIdle() > 0) {
+      socket.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, conf.tcpKeepIdle());
+    }
+    if (conf.tcpKeepCount() > 0) {
+      socket.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, conf.tcpKeepCount());
+    }
+    if (conf.tcpKeepInterval() > 0) {
+      socket.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, conf.tcpKeepInterval());
+    }
+
+    // Bind the socket to a particular interface if the connection property
+    // localSocketAddress has been defined.
+    if (conf.localSocketAddress() != null) {
+      InetSocketAddress localAddress = new InetSocketAddress(conf.localSocketAddress(), 0);
+      socket.bind(localAddress);
+    }
+  }
+}
diff --git a/src/main/java9/module-info.java b/src/main/java9/module-info.java
new file mode 100644
index 0000000..5896c28
--- /dev/null
+++ b/src/main/java9/module-info.java
@@ -0,0 +1,86 @@
+import org.mariadb.jdbc.plugin.codec.*;
+
+module org.mariadb.jdbc {
+  requires transitive java.sql;
+  requires transitive java.management;
+  requires transitive java.naming;
+  requires transitive java.security.jgss;
+  requires transitive jdk.net;
+  requires waffle.jna;
+  requires static software.amazon.awssdk.services.rds;
+  requires static software.amazon.awssdk.regions;
+  requires static software.amazon.awssdk.auth;
+  requires static com.sun.jna;
+  requires static com.sun.jna.platform;
+  requires static org.slf4j;
+
+  exports org.mariadb.jdbc;
+  exports org.mariadb.jdbc.client;
+  exports org.mariadb.jdbc.client.util;
+  exports org.mariadb.jdbc.client.socket;
+  exports org.mariadb.jdbc.message;
+  exports org.mariadb.jdbc.type;
+  exports org.mariadb.jdbc.export;
+  exports org.mariadb.jdbc.plugin;
+  exports org.mariadb.jdbc.plugin.codec;
+  exports org.mariadb.jdbc.plugin.authentication.standard;
+  exports org.mariadb.jdbc.plugin.authentication.addon;
+  exports org.mariadb.jdbc.plugin.credential.aws;
+  exports org.mariadb.jdbc.plugin.credential.env;
+  exports org.mariadb.jdbc.plugin.credential.system;
+  exports org.mariadb.jdbc.plugin.tls.main;
+
+  uses java.sql.Driver;
+  uses org.mariadb.jdbc.plugin.CredentialPlugin;
+  uses org.mariadb.jdbc.plugin.Codec;
+  uses org.mariadb.jdbc.plugin.AuthenticationPlugin;
+  uses org.mariadb.jdbc.plugin.TlsSocketPlugin;
+
+  provides java.sql.Driver with
+      org.mariadb.jdbc.Driver;
+  provides org.mariadb.jdbc.plugin.AuthenticationPlugin with
+      org.mariadb.jdbc.plugin.authentication.addon.ClearPasswordPlugin,
+      org.mariadb.jdbc.plugin.authentication.addon.SendGssApiAuthPacket,
+      org.mariadb.jdbc.plugin.authentication.standard.Ed25519PasswordPlugin,
+      org.mariadb.jdbc.plugin.authentication.standard.NativePasswordPlugin,
+      org.mariadb.jdbc.plugin.authentication.standard.SendPamAuthPacket,
+      org.mariadb.jdbc.plugin.authentication.standard.CachingSha2PasswordPlugin;
+  provides org.mariadb.jdbc.plugin.Codec with
+      BigDecimalCodec,
+      BigIntegerCodec,
+      BitSetCodec,
+      BlobCodec,
+      BooleanCodec,
+      ByteArrayCodec,
+      ByteCodec,
+      ClobCodec,
+      DateCodec,
+      DoubleCodec,
+      DurationCodec,
+      FloatCodec,
+      GeometryCollectionCodec,
+      IntCodec,
+      LineStringCodec,
+      LocalDateCodec,
+      LocalDateTimeCodec,
+      LocalTimeCodec,
+      LongCodec,
+      MultiLinestringCodec,
+      MultiPointCodec,
+      MultiPolygonCodec,
+      PointCodec,
+      PolygonCodec,
+      ReaderCodec,
+      ShortCodec,
+      StreamCodec,
+      StringCodec,
+      TimeCodec,
+      TimestampCodec,
+      ZonedDateTimeCodec;
+  provides org.mariadb.jdbc.plugin.CredentialPlugin with
+      org.mariadb.jdbc.plugin.credential.aws.AwsIamCredentialPlugin,
+      org.mariadb.jdbc.plugin.credential.env.EnvCredentialPlugin,
+      org.mariadb.jdbc.plugin.credential.system.PropertiesCredentialPlugin;
+  provides org.mariadb.jdbc.plugin.TlsSocketPlugin with
+      org.mariadb.jdbc.plugin.tls.main.DefaultTlsSocketPlugin;
+}
diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..07332bc
--- /dev/null
+++ b/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Multi-Release: true
diff --git a/src/main/resources/META-INF/services/java.sql.Driver b/src/main/resources/META-INF/services/java.sql.Driver
new file mode 100644
index 0000000..ad8b171
--- /dev/null
+++ b/src/main/resources/META-INF/services/java.sql.Driver
@@ -0,0 +1 @@
+org.mariadb.jdbc.Driver
\ No newline at end of file
diff --git a/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.AuthenticationPlugin b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.AuthenticationPlugin
new file mode 100644
index 0000000..63d4f49
--- /dev/null
+++ b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.AuthenticationPlugin
@@ -0,0 +1,6 @@
+org.mariadb.jdbc.plugin.authentication.addon.ClearPasswordPlugin
+org.mariadb.jdbc.plugin.authentication.addon.SendGssApiAuthPacket
+org.mariadb.jdbc.plugin.authentication.standard.Ed25519PasswordPlugin
+org.mariadb.jdbc.plugin.authentication.standard.NativePasswordPlugin
+org.mariadb.jdbc.plugin.authentication.standard.SendPamAuthPacket
+org.mariadb.jdbc.plugin.authentication.standard.CachingSha2PasswordPlugin
\ No newline at end of file
diff --git a/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.Codec b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.Codec
new file mode 100644
index 0000000..3335aa2
--- /dev/null
+++ b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.Codec
@@ -0,0 +1,34 @@
+org.mariadb.jdbc.plugin.codec.BigDecimalCodec
+org.mariadb.jdbc.plugin.codec.BigIntegerCodec
+org.mariadb.jdbc.plugin.codec.BitSetCodec
+org.mariadb.jdbc.plugin.codec.BlobCodec
+org.mariadb.jdbc.plugin.codec.BooleanCodec
+org.mariadb.jdbc.plugin.codec.ByteArrayCodec
+org.mariadb.jdbc.plugin.codec.ByteCodec
+org.mariadb.jdbc.plugin.codec.ClobCodec
+org.mariadb.jdbc.plugin.codec.DateCodec
+org.mariadb.jdbc.plugin.codec.DoubleCodec
+org.mariadb.jdbc.plugin.codec.DurationCodec
+org.mariadb.jdbc.plugin.codec.FloatCodec
+org.mariadb.jdbc.plugin.codec.GeometryCollectionCodec
+org.mariadb.jdbc.plugin.codec.IntCodec
+org.mariadb.jdbc.plugin.codec.InstantCodec
+org.mariadb.jdbc.plugin.codec.OffsetDateTimeCodec
+org.mariadb.jdbc.plugin.codec.LineStringCodec
+org.mariadb.jdbc.plugin.codec.LocalDateCodec
+org.mariadb.jdbc.plugin.codec.LocalDateTimeCodec
+org.mariadb.jdbc.plugin.codec.LocalTimeCodec
+org.mariadb.jdbc.plugin.codec.LongCodec
+org.mariadb.jdbc.plugin.codec.MultiLinestringCodec
+org.mariadb.jdbc.plugin.codec.MultiPointCodec
+org.mariadb.jdbc.plugin.codec.MultiPolygonCodec
+org.mariadb.jdbc.plugin.codec.PointCodec
+org.mariadb.jdbc.plugin.codec.PolygonCodec
+org.mariadb.jdbc.plugin.codec.ReaderCodec
+org.mariadb.jdbc.plugin.codec.ShortCodec
+org.mariadb.jdbc.plugin.codec.StreamCodec
+org.mariadb.jdbc.plugin.codec.StringCodec
+org.mariadb.jdbc.plugin.codec.TimeCodec
+org.mariadb.jdbc.plugin.codec.TimestampCodec
+org.mariadb.jdbc.plugin.codec.UuidCodec
+org.mariadb.jdbc.plugin.codec.ZonedDateTimeCodec
diff --git a/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.CredentialPlugin b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.CredentialPlugin
new file mode 100644
index 0000000..cc51428
--- /dev/null
+++ b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.CredentialPlugin
@@ -0,0 +1,3 @@
+org.mariadb.jdbc.plugin.credential.aws.AwsIamCredentialPlugin
+org.mariadb.jdbc.plugin.credential.env.EnvCredentialPlugin
+org.mariadb.jdbc.plugin.credential.system.PropertiesCredentialPlugin
diff --git a/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.TlsSocketPlugin b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.TlsSocketPlugin
new file mode 100644
index 0000000..471e4d2
--- /dev/null
+++ b/src/main/resources/META-INF/services/org.mariadb.jdbc.plugin.TlsSocketPlugin
@@ -0,0 +1 @@
+org.mariadb.jdbc.plugin.tls.main.DefaultTlsSocketPlugin
\ No newline at end of file
diff --git a/src/main/resources/deprecated.properties b/src/main/resources/deprecated.properties
new file mode 100644
index 0000000..396dc2c
--- /dev/null
+++ b/src/main/resources/deprecated.properties
@@ -0,0 +1,3 @@
+useSsl=`useSsl` option is deprecated, replaced by option `sslMode`
+trustServerCertificate=`trustServerCertificate` option is deprecated, replaced by setting option `sslMode=trust`
+disableSslHostnameVerification=`disableSslHostnameVerification` option is deprecated, replaced by setting option `sslMode=verify-ca`
diff --git a/src/main/resources/driver.properties b/src/main/resources/driver.properties
new file mode 100644
index 0000000..db5ff93
--- /dev/null
+++ b/src/main/resources/driver.properties
@@ -0,0 +1,69 @@
+user=Database user name
+password=Password of database user
+database=Database
+socketFactory=to use a custom socket factory, set it to the full name of the class that implements javax.net.SocketFactory.
+connectTimeout=The connect timeout value, in milliseconds, or zero for no timeout.
+pipe=On Windows, specify named pipe name to connect.
+localSocket=Permits connecting to the database via Unix domain socket, if the server allows it. The value is the path of Unix domain socket (i.e "socket" database parameter : select @@socket)
+tcpKeepAlive=Sets corresponding option on the connection socket. Default: True
+tcpAbortiveClose=This option can be used in environments where connections are created and closed in rapid succession. Often, it is not possible to create a socket in such an environment after a while, since all local �ephemeral� ports are used up by TCP connections in TCP_WAIT state. Using tcpAbortiveClose works around this problem by resetting TCP connections (abortive or hard close) rather than doing an orderly close. It is accomplished by using socket.setSoLinger(true,0) for abortive close
+localSocketAddress=Hostname or IP address to bind the connection socket to a local (UNIX domain) socket.
+socketTimeout=Defined the network socket timeout (SO_TIMEOUT) in milliseconds. Value of 0 disables this timeout.If the goal is to set a timeout for all queries, since MariaDB 10.1.1, the server has permitted a solution to limit the query time by setting a system variable, max_statement_time. The advantage is that the connection then is still usable. Default: 0ms.
+allowMultiQueries=permit multi-queries like insert into ab (i) values (1); insert into ab (i) values (2). Default: false.
+useCompression=Compresses the exchange with the database through gzip. This permits better performance when the database is not in the same location.
+blankTableNameMeta=Resultset metadata getTableName always return blank. This option is mainly for ORACLE db compatibility.
+credentialType=Indicate the credential plugin type to use. Plugin must be present in classpath
+sslMode=Indicate SSL demand. Possible value disable, trust (no certificate and hostname validation), verify-ca (Encryption, certificates validation, BUT no hostname verification), verify-full (Standard SSL use: Encryption, certificate validation and hostname)
+enabledSslCipherSuites=Force TLS/SSL cipher (comma separated list). Example : "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"
+sessionVariables=<var>=<value> pairs separated by comma, mysql session variables, set upon establishing successful connection.
+tinyInt1isBit=Datatype mapping flag, handle MySQL Tiny as BIT(boolean).
+yearIsDateType=Year is date type, rather than numerical.
+dumpQueriesOnException=If set to 'true', an exception is thrown during query execution containing a query string.
+prepStmtCacheSize=if useServerPrepStmts = true, defines the prepared statement cache size that option `cachePrepStmts` use. Default: 250
+useAffectedRows=If false (default), use "found rows" for the row count of statements. This corresponds to the JDBC standard. If true, use "affected rows" for the row count. This changes the behavior of, for example, UPDATE... ON DUPLICATE KEY statements.
+useServerPrepStmts=PrepareStatement are prepared on the server side before executing. The applications that repeatedly use the same queries have value to activate this option, but the general case is to use the direct command (text protocol).
+connectionAttributes=When performance_schema is active, permit to send server some client information in a key;value pair format (example: connectionAttributes=key1:value1,key2,value2). Those informations can be retrieved on server within tables performance_schema.session_connect_attrs and performance_schema.session_account_connect_attrs. This can permit from server an identification of client/application
+useBulkStmts=Use dedicated COM_STMT_BULK_EXECUTE protocol for batch insert when possible. (batch without Statement.RETURN_GENERATED_KEYS and streams) to have faster batch. (significant only on >= MariaDB 10.2.7). Default: false.
+autocommit=Set default autocommit value on connection initialization. Default: true.
+includeInnodbStatusInDeadlockExceptions=add "SHOW ENGINE INNODB STATUS" result to exception trace when having a deadlock exception.
+includeThreadDumpInDeadlockExceptions=add thread dump to exception trace when having a deadlock exception.
+servicePrincipalName=When using GSSAPI authentication, use this value as the Service Principal Name (SPN) instead of the one defined for the user account on the database server.
+defaultFetchSize=The driver will call setFetchSize(n) with this value on all newly-created Statements. Default: 0.
+tlsSocketType=Indicate the TLS org.mariadb.jdbc.tls.TlsSocketPlugin plugin type to use. Plugin must be present in classpath
+maxQuerySizeToLog=Only the first characters corresponding to this options size will be displayed in logs. Default: 1024
+retriesAllDown=When the connector is performing a failover and all hosts are down, this parameter defines the maximum number of connection attempts the connector will make before throwing an exception. Default: 120 seconds.
+galeraAllowedState=Usually, Connection.isValid just send an empty packet to server, and server send a small response to ensure connectivity. When this option is set, connector will ensure Galera server state "wsrep_local_state" correspond to allowed values (separated by comma). example "4,5", recommended is "4". see galera state to know more.
+enabledSslProtocolSuites=Force TLS/SSL protocol to a specific set of TLS versions (comma separated list). Example : "TLSv1, TLSv1.1, TLSv1.2"
+pool=Use pool. This option is useful only if not using a DataSource object, but only a connection object. Default: false.
+poolName=Pool name that permits identifying threads. default: auto-generated as MariaDb-pool-<pool-index>
+maxPoolSize=The maximum number of physical connections that the pool should contain. Default: 8.
+minPoolSize=When connections are removed due to not being used for longer than than "maxIdleTime", connections are closed and removed from the pool. "minPoolSize" indicates the number of physical connections the pool should keep available at all times. Should be less or equal to maxPoolSize.
+maxIdleTime=The maximum amount of time in seconds that a connection can stay in the pool when not used. This value must always be below @wait_timeout value - 45s. Default: 600 in seconds (=10 minutes), minimum value is 60 seconds.
+registerJmxPool=Register JMX monitoring pools. Default: true.
+poolValidMinDelay=When asking a connection to pool, the pool will validate the connection state. "poolValidMinDelay" permits disabling this validation if the connection has been borrowed recently avoiding useless verifications in case of frequent reuse of connections. 0 means validation is done each time the connection is asked. Default: 1000 (in milliseconds).
+useResetConnection=When a connection is closed() (given back to pool), the pool resets the connection state. Setting this option, the prepare command will be deleted, session variables changed will be reset, and user variables will be destroyed when the server permits it (>= MariaDB 10.2.4, >= MySQL 5.7.3), permitting saving memory on the server if the application make extensive use of variables. Must not be used with the useServerPrepStmts option. Default: false.
+serverSslCert=Permits providing server's certificate in DER form, or server's CA certificate. The server will be added to trustStor. This permits a self-signed certificate to be trusted. Can be used in one of 3 forms : * serverSslCert=/path/to/cert.pem (full path to certificate) * serverSslCert=classpath:relative/cert.pem (relative to current classpath) * or as verbatim DER-encoded certificate string "------BEGIN CERTIFICATE-----" .
+serverRsaPublicKeyFile=Indicate path to RSA server public key file for sha256_password and caching_sha2_password authentication password
+allowPublicKeyRetrieval=Authorize client to retrieve RSA server public key when serverRsaPublicKeyFile is not set (for sha256_password and caching_sha2_password authentication password). Default: false.
+useReadAheadInput=use a buffered inputSteam that read socket available data. This cost a bit more in CPU, but permit returning result-set faster. Default true
+cachePrepStmts=enable/disable prepare Statement cache. When enable, PreparedStatement.close won't close prepare immediately, keeping a pool of most used prepared results. Default true.
+timezone=permits to force session timezone in case of client having a different timezone compare to server. The option `timezone` can have 3 types of value: 'disabled' (default) : connector doesn't change time_zone. '<a timezone>': connector will set connection variable to value. see timezone consideration tp know more
+transactionReplay=When having a failover, can current transaction being re-executed, having a completely transparent failover. All commands must be idempotent. Default false.
+transactionReplaySize=replay cache buffer maximum size. If a transaction has more command that this size and a failover occurs, transaction will then not be replayed, just throwing an exception error. (Integer) default 64.
+allowLocalInfile=Indicate if LOAD DATA LOCAL INFILE commands are permitted. This will disable all pipelining implementation. Default false.
+geometryDefaultType=Indicate what default Object type Geometry a resultset.getObject must return. null or empty is WKB byte array. 'default' will return org.mariadb.mariadb.jdbc.type Object. Default null
+keyStore=File path of the keyStore file that contain client private key store and associate certificates (similar to java System property "javax.net.ssl.keyStore", but ensure that only the private key's entries are used)
+keyStorePassword="Password for the client certificate keyStore (similar to java System property "javax.net.ssl.keyStorePassword")
+keyStoreType=indicate key store type (JKS/PKCS12). default is null, then using java default type
+transactionIsolation=Default transaction isolation level. Possible values READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. default REPEATABLE-READ
+restrictedAuth=if set, restrict authentication plugin to secure list. Default provided plugins are mysql_native_password,client_ed25519,auth_gssapi_client,caching_sha2_password,dialog and mysql_clear_password. (String) Default null
+tcpKeepIdle=permit setting socket TCP_KEEPIDLE value. Only valid for java 11+(for previous version, this option will have no use). (Integer) Default null
+tcpKeepCount=permit setting socket TCP_KEEPCOUNT value. Only valid for java 11+(for previous version, this option will have no use). (Integer) Default null
+tcpKeepInterval=permit setting socket TCP_KEEPINTERVAL value. Only valid for java 11+(for previous version, this option will have no use). (Integer) Default null
+useMysqlMetadata=force DatabaseMetadata.getDatabaseProductName() to return "MySQL" (for compatibility reason)
+maxAllowedPacket=permit to driver to avoid sending command with size > to server max_allowed_packet, throwing an error in place of server dropping the connection.
+createDatabaseIfNotExist=the specified database in the url will be created if nonexistent. Default: false
+initSql=Initial command to execute on new connection creation
+transformedBitIsBoolean=Indicate for TINYINT(1) in column metadata that type is BOOLEAN in place of BIT 
+disablePipeline=option permitting disabling pipelining
+uuidAsString=must uuid fields return as String and not java.util.UUID when using getObject()
\ No newline at end of file
diff --git a/src/main/resources/mariadb.properties b/src/main/resources/mariadb.properties
new file mode 100644
index 0000000..e5683df
--- /dev/null
+++ b/src/main/resources/mariadb.properties
@@ -0,0 +1 @@
+version=${project.version}
\ No newline at end of file
diff --git a/src/test/java/org/mariadb/jdbc/integration/BatchTest.java b/src/test/java/org/mariadb/jdbc/integration/BatchTest.java
new file mode 100644
index 0000000..814c750
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/BatchTest.java
@@ -0,0 +1,493 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import java.util.Calendar;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+
+public class BatchTest extends Common {
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    after2();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE BatchTest (t1 int not null primary key auto_increment, t2 LONGTEXT)");
+    createSequenceTables();
+    stmt.execute("CREATE TABLE timestampCal(id int, val TIMESTAMP)");
+  }
+
+  @AfterAll
+  public static void after2() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS timestampCal");
+    stmt.execute("DROP TABLE IF EXISTS BatchTest");
+  }
+
+  @Test
+  public void wrongParameter() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      wrongParameter(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts=true")) {
+      wrongParameter(con);
+    }
+  }
+
+  public void wrongParameter(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE BatchTest");
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+      prep.setInt(1, 5);
+      try {
+        prep.addBatch();
+      } catch (SQLTransientConnectionException e) {
+        assertTrue(e.getMessage().contains("Parameter at position 2 is not set"));
+      }
+      try {
+        prep.addBatch();
+      } catch (SQLTransientConnectionException e) {
+        assertTrue(
+            e.getMessage().contains("Parameter at position 2 is not set")
+                || e.getMessage()
+                    .contains(
+                        "batch set of parameters differ from previous set. All parameters must be"
+                            + " set"));
+      }
+
+      prep.setInt(1, 5);
+      prep.setString(3, "wrong position");
+      Common.assertThrowsContains(
+          SQLTransientConnectionException.class,
+          prep::addBatch,
+          "Parameter at position 2 is not set");
+
+      prep.setInt(1, 5);
+      prep.setString(2, "ok");
+      prep.addBatch();
+      prep.setString(2, "without position 1");
+      prep.addBatch();
+    }
+  }
+
+  @Test
+  public void differentParameterType() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false&useBulkStmts=false")) {
+      differentParameterType(con, false);
+    }
+    try (Connection con = createCon("&useServerPrepStmts=false&useBulkStmts=true")) {
+      differentParameterType(con, isMariaDBServer() && !isXpand());
+    }
+    try (Connection con =
+        createCon("&useServerPrepStmts=false&useBulkStmts=true&disablePipeline")) {
+      differentParameterType(con, isMariaDBServer() && !isXpand());
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts=false")) {
+      differentParameterType(con, false);
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts&allowLocalInfile=false")) {
+      differentParameterType(con, isMariaDBServer() && !isXpand());
+    }
+    try (Connection con = createCon("&useServerPrepStmts=false&allowLocalInfile")) {
+      differentParameterType(con, isMariaDBServer() && !isXpand());
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts=false")) {
+      differentParameterType(con, false);
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts")) {
+      differentParameterType(con, isMariaDBServer() && !isXpand());
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts&allowLocalInfile=false")) {
+      differentParameterType(con, isMariaDBServer() && !isXpand());
+    }
+    try (Connection con =
+        createCon("&useServerPrepStmts&useBulkStmts=false&disablePipeline=true")) {
+      differentParameterType(con, false);
+    }
+  }
+
+  public void differentParameterType(Connection con, boolean expectSuccessUnknown)
+      throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE BatchTest");
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, "1");
+      prep.addBatch();
+
+      prep.setInt(1, 2);
+      prep.setInt(2, 2);
+      prep.addBatch();
+      prep.setInt(1, 3);
+      prep.setNull(2, Types.INTEGER);
+      prep.addBatch();
+      int[] res = prep.executeBatch();
+      assertEquals(3, res.length);
+      if (expectSuccessUnknown) {
+        assertEquals(Statement.SUCCESS_NO_INFO, res[0]);
+        assertEquals(Statement.SUCCESS_NO_INFO, res[1]);
+        assertEquals(Statement.SUCCESS_NO_INFO, res[2]);
+      } else {
+        assertEquals(1, res[0]);
+        assertEquals(1, res[1]);
+        assertEquals(1, res[2]);
+      }
+    }
+    ResultSet rs = stmt.executeQuery("SELECT * FROM BatchTest");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertEquals("2", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(3, rs.getInt(1));
+    assertNull(rs.getString(2));
+    assertFalse(rs.next());
+    stmt.execute("TRUNCATE BatchTest");
+
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+      prep.setInt(1, 1);
+      prep.setInt(2, 1);
+      prep.addBatch();
+
+      prep.setInt(1, 2);
+      prep.setInt(2, 2);
+      prep.addBatch();
+      int[] res = prep.executeBatch();
+      assertEquals(2, res.length);
+      if (expectSuccessUnknown) {
+        assertEquals(Statement.SUCCESS_NO_INFO, res[0]);
+        assertEquals(Statement.SUCCESS_NO_INFO, res[1]);
+      } else {
+        assertEquals(1, res[0]);
+        assertEquals(1, res[1]);
+      }
+    }
+    rs = stmt.executeQuery("SELECT * FROM BatchTest");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertEquals("2", rs.getString(2));
+    assertFalse(rs.next());
+
+    stmt.execute("TRUNCATE BatchTest");
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+      prep.setInt(1, 1);
+      prep.setInt(2, 1);
+      prep.addBatch();
+
+      int[] res = prep.executeBatch();
+      assertEquals(1, res.length);
+      assertEquals(1, res[0]);
+    }
+    rs = stmt.executeQuery("SELECT * FROM BatchTest");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1", rs.getString(2));
+    assertFalse(rs.next());
+
+    stmt.execute("TRUNCATE BatchTest");
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, "1");
+      prep.addBatch();
+
+      prep.setInt(1, 2);
+      prep.setInt(2, 2);
+      prep.addBatch();
+      int[] res = prep.executeBatch();
+      assertEquals(2, res.length);
+      assertEquals(1, res[0]);
+      assertEquals(1, res[1]);
+
+      stmt.execute("TRUNCATE BatchTest");
+
+      stmt.setFetchSize(1);
+      rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10");
+      rs.next();
+
+      prep.setInt(1, 1);
+      prep.setString(2, "1");
+      prep.addBatch();
+
+      prep.setInt(1, 2);
+      prep.setInt(2, 2);
+      prep.addBatch();
+      res = prep.executeBatch();
+      assertEquals(2, res.length);
+      assertEquals(1, res[0]);
+      assertEquals(1, res[1]);
+    }
+    rs = stmt.executeQuery("SELECT * FROM BatchTest");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertEquals("2", rs.getString(2));
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void largeBatch() throws SQLException {
+    for (int i = 0; i < 32; i++) {
+      boolean useServerPrepStmts = (i & 2) > 0;
+      boolean useBulkStmts = (i & 4) > 0;
+      boolean allowLocalInfile = (i & 8) > 0;
+      boolean useCompression = (i & 16) > 0;
+
+      try (Connection con =
+          createCon(
+              String.format(
+                  "&useServerPrepStmts=%s&useBulkStmts=%s&allowLocalInfile=%s&useCompression=%s",
+                  useServerPrepStmts, useBulkStmts, allowLocalInfile, useCompression))) {
+        largeBatch(con);
+      }
+    }
+  }
+
+  public void largeBatch(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE BatchTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, "1");
+      prep.addBatch();
+
+      prep.setInt(1, 2);
+      prep.setInt(2, 2);
+      prep.addBatch();
+      long[] res = prep.executeLargeBatch();
+      assertEquals(2, res.length);
+      assertEquals(1, res[0]);
+      assertEquals(1, res[1]);
+    }
+    ResultSet rs = stmt.executeQuery("SELECT * FROM BatchTest");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertEquals("2", rs.getString(2));
+    assertFalse(rs.next());
+    con.commit();
+  }
+
+  @Test
+  public void bulkPacketSplitMaxAllowedPacket() throws SQLException {
+    Assumptions.assumeTrue(runLongTest());
+    int maxAllowedPacket = getMaxAllowedPacket();
+    bulkPacketSplit(2, maxAllowedPacket - 40, maxAllowedPacket);
+    if (maxAllowedPacket >= 16 * 1024 * 1024) bulkPacketSplit(2, maxAllowedPacket - 40, null);
+  }
+
+  @Test
+  public void bulkPacketSplitMultiplePacket() throws SQLException {
+    Assumptions.assumeTrue(runLongTest());
+    int maxAllowedPacket = getMaxAllowedPacket();
+    bulkPacketSplit(4, getMaxAllowedPacket() / 3, maxAllowedPacket);
+    if (maxAllowedPacket >= 16 * 1024 * 1024) bulkPacketSplit(4, getMaxAllowedPacket() / 3, null);
+  }
+
+  @Test
+  public void bulkPacketSplitHugeNbPacket() throws SQLException {
+    Assumptions.assumeTrue(runLongTest());
+    int maxAllowedPacket = getMaxAllowedPacket();
+    bulkPacketSplit(getMaxAllowedPacket() / 8000, 20, maxAllowedPacket);
+    if (maxAllowedPacket >= 16 * 1024 * 1024)
+      bulkPacketSplit(getMaxAllowedPacket() / 8000, 20, null);
+  }
+
+  public void bulkPacketSplit(int nb, int len, Integer maxAllowedPacket) throws SQLException {
+    byte[] arr = new byte[Math.min(16 * 1024 * 1024, len)];
+    for (int pos = 0; pos < arr.length; pos++) {
+      arr[pos] = (byte) ((pos % 60) + 65);
+    }
+
+    try (Connection con =
+        createCon(
+            "&useServerPrepStmts&useBulkStmts"
+                + (maxAllowedPacket != null ? "&maxAllowedPacket=" + maxAllowedPacket : ""))) {
+      Statement stmt = con.createStatement();
+      stmt.execute("TRUNCATE BatchTest");
+      stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+      try (PreparedStatement prep =
+          con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+        for (int i = 1; i <= nb; i++) {
+          prep.setInt(1, i);
+          prep.setBytes(2, arr);
+          prep.addBatch();
+        }
+
+        int[] res = prep.executeBatch();
+        assertEquals(nb, res.length);
+        for (int i = 0; i < nb; i++) {
+          assertTrue(res[i] == 1 || res[i] == Statement.SUCCESS_NO_INFO);
+        }
+      }
+      ResultSet rs = stmt.executeQuery("SELECT * FROM BatchTest");
+      for (int i = 1; i <= nb; i++) {
+        assertTrue(rs.next());
+        assertEquals(i, rs.getInt(1));
+        assertArrayEquals(arr, rs.getBytes(2));
+      }
+      assertFalse(rs.next());
+
+      // check same ending with error
+      stmt.execute("TRUNCATE BatchTest");
+      try (PreparedStatement prep =
+          con.prepareStatement("INSERT INTO BatchTest(t1, t2) VALUES (?,?)")) {
+        for (int i = 1; i <= nb; i++) {
+          prep.setInt(1, i);
+          prep.setBytes(2, arr);
+          prep.addBatch();
+        }
+        prep.setInt(1, nb);
+        prep.setBytes(2, arr);
+        prep.addBatch();
+
+        BatchUpdateException e =
+            Assertions.assertThrows(BatchUpdateException.class, prep::executeBatch);
+        int[] updateCounts = e.getUpdateCounts();
+        assertEquals(nb + 1, updateCounts.length);
+      }
+      con.rollback();
+      con.rollback();
+    }
+  }
+
+  @Test
+  public void batchWithError() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false&useBulkStmts=false")) {
+      batchWithError(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts=false&useBulkStmts=true")) {
+      batchWithError(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts=false")) {
+      batchWithError(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts=true")) {
+      batchWithError(con);
+    }
+    try (Connection con =
+        createCon("&useServerPrepStmts=false&useBulkStmts=false&allowLocalInfile")) {
+      batchWithError(con);
+    }
+    try (Connection con =
+        createCon("&useServerPrepStmts=false&useBulkStmts=true&allowLocalInfile")) {
+      batchWithError(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts=false&allowLocalInfile")) {
+      batchWithError(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts&useBulkStmts=true&allowLocalInfile")) {
+      batchWithError(con);
+    }
+  }
+
+  private void batchWithError(Connection con) throws SQLException {
+    Assumptions.assumeTrue(isMariaDBServer());
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS prepareError");
+    stmt.setFetchSize(3);
+    stmt.execute("CREATE TABLE prepareError(id int primary key, val varchar(10))");
+    stmt.execute("INSERT INTO prepareError(id, val) values (1, 'val1')");
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO prepareError(id, val) VALUES (?,?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, "val3");
+      prep.addBatch();
+      // Duplicate entry '1' for key 'PRIMARY'
+      assertThrows(BatchUpdateException.class, prep::executeBatch);
+    }
+  }
+
+  private class TimestampCal {
+    private Timestamp val;
+    private int id;
+
+    public TimestampCal(Timestamp val, int id) {
+      this.val = val;
+      this.id = id;
+    }
+
+    public Timestamp getVal() {
+      return val;
+    }
+
+    public int getId() {
+      return id;
+    }
+
+    @Override
+    public String toString() {
+      return "TimestampCal{" + "val=" + val + ", id=" + id + '}';
+    }
+  }
+
+  @Test
+  public void ensureCalendarSync() throws SQLException {
+    Assumptions.assumeTrue(isMariaDBServer() && !isXpand());
+    // to ensure that calendar is use at the same time, using BULK command
+    TimestampCal[] t1 = new TimestampCal[50];
+    for (int i = 0; i < 50; i++) {
+      t1[i] = new TimestampCal(Timestamp.valueOf((1970 + i) + "-01-31 12:00:00.0"), i);
+    }
+    TimestampCal[] t2 = new TimestampCal[50];
+    for (int i = 0; i < 50; i++) {
+      t2[i] = new TimestampCal(Timestamp.valueOf((1970 + i) + "-12-01 01:12:15.0"), i + 50);
+    }
+
+    Calendar cal = Calendar.getInstance();
+    sharedConn.createStatement().execute("START TRANSACTION");
+    int inserts = Stream.of(t1, t2).parallel().mapToInt(l -> insertTimestamp(l, cal)).sum();
+    assertEquals(100, inserts);
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM timestampCal order by ID");
+    for (int i = 0; i < 50; i++) {
+      rs.next();
+      assertEquals(t1[i].getVal().toString(), rs.getTimestamp(2, cal).toString());
+    }
+    for (int i = 0; i < 50; i++) {
+      rs.next();
+      assertEquals(t2[i].getVal().toString(), rs.getTimestamp(2, cal).toString());
+    }
+    sharedConn.commit();
+  }
+
+  private int insertTimestamp(TimestampCal[] vals, Calendar cal) {
+    try (Connection con = createCon()) {
+      try (PreparedStatement prep =
+          con.prepareStatement("INSERT INTO timestampCal(val, id) VALUES (?,?)")) {
+        for (int i = 0; i < vals.length; i++) {
+          prep.setTimestamp(1, vals[i].getVal(), cal);
+          prep.setInt(2, vals[i].getId());
+          prep.addBatch();
+        }
+        return prep.executeBatch().length;
+      }
+    } catch (SQLException e) {
+      e.printStackTrace();
+      return -1;
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/BlobTest.java b/src/test/java/org/mariadb/jdbc/integration/BlobTest.java
new file mode 100644
index 0000000..d78dfa8
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/BlobTest.java
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.SQLException;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbBlob;
+
+public class BlobTest extends Common {
+
+  private final byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5};
+
+  @Test
+  public void length() {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    assertEquals(6, blob.length());
+
+    MariaDbBlob blob2 = new MariaDbBlob(bytes, 2, 3);
+    assertEquals(3, blob2.length());
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    assertArrayEquals(bytes, blob.getBytes(1, 6));
+    assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 0}, blob.getBytes(1, 7));
+    assertArrayEquals(new byte[] {0, 1}, blob.getBytes(1, 2));
+
+    MariaDbBlob blob2 = new MariaDbBlob(bytes, 2, 3);
+    assertArrayEquals(new byte[] {2, 3, 4}, blob2.getBytes(1, 3));
+    assertArrayEquals(new byte[] {2, 3, 4, 0, 0, 0}, blob2.getBytes(1, 6));
+    assertArrayEquals(new byte[] {2, 3}, blob2.getBytes(1, 2));
+    assertArrayEquals(new byte[] {3, 4, 0}, blob2.getBytes(2, 3));
+    assertArrayEquals(new byte[] {3, 4, 0, 0, 0, 0}, blob2.getBytes(2, 6));
+    assertArrayEquals(new byte[] {3, 4}, blob2.getBytes(2, 2));
+
+    try {
+      blob2.getBytes(0, 3);
+      fail("must have thrown exception, min pos is 1");
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    assureInputStreamEqual(bytes, blob.getBinaryStream(1, 6));
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> assureInputStreamEqual(new byte[] {0, 1, 2, 3, 4, 5, 0}, blob.getBinaryStream(1, 7)),
+        "Out of range (position + length - 1 > streamSize)");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> assureInputStreamEqual(new byte[] {0, 1, 2, 3, 4, 5, 0}, blob.getBinaryStream(-2, 7)),
+        "Out of range (position should be > 0)");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> assureInputStreamEqual(new byte[] {0, 1, 2, 3, 4, 5, 0}, blob.getBinaryStream(20, 7)),
+        "Out of range (position > stream size)");
+
+    assureInputStreamEqual(new byte[] {0, 1}, blob.getBinaryStream(1, 2));
+
+    MariaDbBlob blob2 = new MariaDbBlob(bytes, 2, 3);
+    assureInputStreamEqual(new byte[] {2, 3, 4}, blob2.getBinaryStream(1, 3));
+    try {
+      assureInputStreamEqual(new byte[] {2, 3, 4, 0, 0, 0}, blob2.getBinaryStream(1, 6));
+      fail("must have thrown exception, max length is 3");
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+    assureInputStreamEqual(new byte[] {2, 3}, blob2.getBinaryStream(1, 2));
+    try {
+      assureInputStreamEqual(new byte[] {3, 4, 0}, blob2.getBinaryStream(2, 3));
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+    assureInputStreamEqual(new byte[] {3, 4}, blob2.getBinaryStream(2, 2));
+
+    try {
+      blob2.getBytes(0, 3);
+      fail("must have thrown exception, min pos is 1");
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+  }
+
+  private void assureInputStreamEqual(byte[] expected, InputStream stream) {
+    try {
+      for (byte expectedVal : expected) {
+        int val = stream.read();
+        assertEquals(expectedVal, val);
+      }
+      assertEquals(-1, stream.read());
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+      fail();
+    }
+  }
+
+  @Test
+  public void position() throws SQLException {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    assertEquals(5, blob.position(new byte[] {4, 5}, 2));
+
+    MariaDbBlob blob2 = new MariaDbBlob(bytes, 2, 4);
+    assertEquals(3, blob2.position(new byte[] {4, 5}, 2));
+    assertEquals(0, blob2.position(new byte[0], 2));
+    assertEquals(-1, blob2.position(new byte[] {4, 9}, 2));
+
+    assertEquals(3, blob2.position(new MariaDbBlob(new byte[] {4, 5}), 2));
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> blob2.position(new byte[] {4, 5}, -2),
+        "Out of range (position should be > 0, " + "but is -2)");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> blob2.position(new byte[] {4, 5}, 20),
+        "Out of range (start > stream size)");
+  }
+
+  @Test
+  public void setBytes() throws SQLException {
+    final byte[] otherBytes = new byte[] {10, 11, 12, 13};
+
+    MariaDbBlob blob = new MariaDbBlob(new byte[0]);
+    blob.setBytes(1, new byte[0]);
+    assertEquals(0, blob.length());
+    blob.setBytes(1, new byte[0], 0, 0);
+    assertEquals(0, blob.length());
+
+    blob = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    blob.setBytes(2, otherBytes);
+    assertArrayEquals(new byte[] {0, 10, 11, 12, 13, 5}, blob.getBytes(1, 6));
+
+    MariaDbBlob blob2 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    blob2.setBytes(4, otherBytes);
+    assertArrayEquals(new byte[] {0, 1, 2, 10, 11, 12, 13}, blob2.getBytes(1, 7));
+
+    MariaDbBlob blob3 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    blob3.setBytes(2, otherBytes);
+    assertArrayEquals(new byte[] {2, 10, 11, 12, 13, 0, 0}, blob3.getBytes(1, 7));
+
+    MariaDbBlob blob4 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    blob4.setBytes(4, otherBytes);
+    assertArrayEquals(new byte[] {2, 3, 4, 10, 11, 12}, blob4.getBytes(1, 6));
+
+    try {
+      MariaDbBlob blob5 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+      blob5.setBytes(0, otherBytes);
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+  }
+
+  @Test
+  public void setBytesOffset() throws SQLException {
+    final byte[] otherBytes = new byte[] {10, 11, 12, 13};
+
+    MariaDbBlob blob = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    blob.setBytes(2, otherBytes, 2, 3);
+    assertArrayEquals(new byte[] {0, 12, 13, 3, 4, 5}, blob.getBytes(1, 6));
+
+    MariaDbBlob blob2 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    blob2.setBytes(4, otherBytes, 3, 2);
+    assertArrayEquals(new byte[] {0, 1, 2, 13, 4, 5, 0}, blob2.getBytes(1, 7));
+
+    MariaDbBlob blob3 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 4);
+    blob3.setBytes(2, otherBytes, 2, 3);
+    assertArrayEquals(new byte[] {2, 12, 13, 5, 0, 0, 0}, blob3.getBytes(1, 7));
+
+    MariaDbBlob blob4 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    blob4.setBytes(4, otherBytes, 2, 2);
+    assertArrayEquals(new byte[] {2, 3, 4, 12, 13, 0}, blob4.getBytes(1, 6));
+
+    MariaDbBlob blob5 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    blob5.setBytes(4, otherBytes, 2, 20);
+    assertArrayEquals(new byte[] {2, 3, 4, 12, 13, 0}, blob5.getBytes(1, 6));
+
+    try {
+      MariaDbBlob blob6 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+      blob6.setBytes(0, otherBytes, 2, 3);
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+  }
+
+  @Test
+  public void setBinaryStream() throws SQLException, IOException {
+    final byte[] otherBytes = new byte[] {10, 11, 12, 13};
+
+    MariaDbBlob blob = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out = blob.setBinaryStream(2);
+    out.write(otherBytes);
+    out.write(0x09);
+    out.write(0x08);
+    assertArrayEquals(new byte[] {0, 10, 11, 12, 13, 9, 8}, blob.getBytes(1, 7));
+
+    MariaDbBlob blob2 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out2 = blob2.setBinaryStream(4);
+    out2.write(otherBytes);
+    assertArrayEquals(new byte[] {0, 1, 2, 10, 11, 12, 13}, blob2.getBytes(1, 7));
+
+    MariaDbBlob blob3 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out3 = blob3.setBinaryStream(2);
+    out3.write(otherBytes);
+    assertArrayEquals(new byte[] {2, 10, 11, 12, 13, 0, 0}, blob3.getBytes(1, 7));
+
+    MariaDbBlob blob4 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out4 = blob4.setBinaryStream(4);
+    out4.write(otherBytes);
+    assertArrayEquals(new byte[] {2, 3, 4, 10, 11, 12}, blob4.getBytes(1, 6));
+
+    MariaDbBlob blob5 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    Common.assertThrowsContains(
+        SQLException.class, () -> blob5.setBinaryStream(0), "Invalid position in blob");
+    Common.assertThrowsContains(
+        IOException.class,
+        () -> blob5.setBinaryStream(2).write(new byte[] {1}, 0, -5),
+        "Invalid len -5");
+    Common.assertThrowsContains(
+        IOException.class,
+        () -> blob5.setBinaryStream(2).write(new byte[] {1}, -2, 1),
+        "Invalid offset -2");
+  }
+
+  @Test
+  public void setBinaryStreamOffset() throws SQLException, IOException {
+    final byte[] otherBytes = new byte[] {10, 11, 12, 13};
+
+    MariaDbBlob blob = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out = blob.setBinaryStream(2);
+    out.write(otherBytes, 2, 3);
+    assertArrayEquals(new byte[] {0, 12, 13, 3, 4, 5}, blob.getBytes(1, 6));
+
+    MariaDbBlob blob2 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out2 = blob2.setBinaryStream(4);
+    out2.write(otherBytes, 3, 2);
+    assertArrayEquals(new byte[] {0, 1, 2, 13, 4, 5, 0}, blob2.getBytes(1, 7));
+
+    MariaDbBlob blob3 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 4);
+    OutputStream out3 = blob3.setBinaryStream(2);
+    out3.write(otherBytes, 2, 3);
+    assertArrayEquals(new byte[] {2, 12, 13, 5, 0, 0, 0}, blob3.getBytes(1, 7));
+
+    MariaDbBlob blob4 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out4 = blob4.setBinaryStream(4);
+    out4.write(otherBytes, 2, 2);
+    assertArrayEquals(new byte[] {2, 3, 4, 12, 13, 0}, blob4.getBytes(1, 6));
+
+    MariaDbBlob blob5 = new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out5 = blob5.setBinaryStream(4);
+    out5.write(otherBytes, 2, 20);
+    assertArrayEquals(new byte[] {2, 3, 4, 12, 13, 0}, blob5.getBytes(1, 6));
+  }
+
+  @Test
+  public void truncate() throws SQLException {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    blob.truncate(20);
+    assertArrayEquals(bytes, blob.getBytes(1, 6));
+    blob.truncate(-5);
+    assertArrayEquals(bytes, blob.getBytes(1, 6));
+    blob.truncate(5);
+    assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 0, 0}, blob.getBytes(1, 7));
+    blob.truncate(0);
+    assertArrayEquals(new byte[] {0, 0}, blob.getBytes(1, 2));
+
+    MariaDbBlob blob2 = new MariaDbBlob(bytes, 2, 3);
+    blob2.truncate(20);
+    assertArrayEquals(new byte[] {2, 3, 4}, blob2.getBytes(1, 3));
+    blob2.truncate(2);
+    assertArrayEquals(new byte[] {2, 3, 0, 0, 0, 0}, blob2.getBytes(1, 6));
+
+    blob2.truncate(1);
+    assertArrayEquals(new byte[] {2, 0}, blob2.getBytes(1, 2));
+  }
+
+  @Test
+  public void free() {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    blob.free();
+    assertEquals(0, blob.length());
+  }
+
+  @Test
+  public void expectedErrors() {
+    Common.assertThrowsContains(
+        IllegalArgumentException.class, () -> new MariaDbBlob(null), "byte array is null");
+    Common.assertThrowsContains(
+        IllegalArgumentException.class, () -> new MariaDbBlob(null, 0, 2), "byte array is null");
+  }
+
+  @Test
+  public void equal() {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    assertEquals(blob, blob);
+    assertEquals(new MariaDbBlob(bytes), blob);
+    assertFalse(blob.equals(null));
+    assertFalse(blob.equals(""));
+    byte[] bytes = new byte[] {5, 1, 2, 3, 4, 5};
+    assertNotEquals(new MariaDbBlob(bytes), blob);
+    assertNotEquals(new MariaDbBlob(new byte[] {5, 1}), blob);
+  }
+
+  @Test
+  public void hashCodeTest() {
+    MariaDbBlob blob = new MariaDbBlob(bytes);
+    assertEquals(-859797942, blob.hashCode());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ClientPreparedStatementParsingTest.java b/src/test/java/org/mariadb/jdbc/integration/ClientPreparedStatementParsingTest.java
new file mode 100644
index 0000000..e3b04b4
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ClientPreparedStatementParsingTest.java
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.ClientParser;
+import org.mariadb.jdbc.util.constants.ServerStatus;
+
+public class ClientPreparedStatementParsingTest extends Common {
+
+  private void checkParsing(String sql, int paramNumber, String[] partsMulti) throws Exception {
+    boolean noBackslashEscapes =
+        (sharedConn.getContext().getServerStatus() & ServerStatus.NO_BACKSLASH_ESCAPES) > 0;
+    ClientParser parser = ClientParser.parameterParts(sql, noBackslashEscapes);
+    assertEquals(paramNumber, parser.getParamCount());
+    int pos = 0;
+    int paramPos = parser.getQuery().length;
+    for (int i = 0; i < parser.getParamPositions().size(); i++) {
+      paramPos = parser.getParamPositions().get(i);
+      assertEquals(partsMulti[i], new String(parser.getQuery(), pos, paramPos - pos));
+      pos = paramPos + 1;
+    }
+    assertEquals(
+        partsMulti[partsMulti.length - 1],
+        new String(parser.getQuery(), pos, parser.getQuery().length - pos));
+  }
+
+  @Test
+  public void stringEscapeParsing() throws Exception {
+    checkParsing(
+        "select '\\'' as a, ? as b, \"\\\"\" as c, ? as d",
+        2,
+        new String[] {"select '\\'' as a, ", " as b, \"\\\"\" as c, ", " as d"});
+  }
+
+  @Test
+  public void testRewritableWithConstantParameter() throws Exception {
+    checkParsing(
+        "INSERT INTO TABLE(col1,col2,col3,col4, col5) VALUES (9, ?, 5, ?, 8) ON DUPLICATE KEY"
+            + " UPDATE col2=col2+10",
+        2,
+        new String[] {
+          "INSERT INTO TABLE(col1,col2,col3,col4, col5) VALUES (9, ",
+          ", 5, ",
+          ", 8) ON DUPLICATE KEY UPDATE col2=col2+10"
+        });
+  }
+
+  @Test
+  public void testComment() throws Exception {
+    checkParsing(
+        "/* insert Select INSERT INTO tt VALUES (?,?,?,?)  */"
+            + " INSERT into "
+            + "/* insert Select INSERT INTO tt VALUES (?,?,?,?)  */"
+            + " tt VALUES "
+            + "/* insert Select INSERT INTO tt VALUES (?,?,?,?)  */"
+            + " (?) "
+            + "/* insert Select INSERT INTO tt VALUES (?,?,?,?)  */",
+        1,
+        new String[] {
+          "/* insert Select INSERT INTO tt VALUES (?,?,?,?)  */"
+              + " INSERT into "
+              + "/* insert Select INSERT INTO tt VALUES (?,?,?,?)  */"
+              + " tt VALUES "
+              + "/* insert Select INSERT INTO tt VALUES (?,?,?,?)  */"
+              + " (",
+          ") /* insert Select INSERT INTO tt VALUES (?,?,?,?)  */"
+        });
+  }
+
+  @Test
+  public void testRewritableWithConstantParameterAndParamAfterValue() throws Exception {
+    checkParsing(
+        "INSERT INTO TABLE(col1,col2,col3,col4, col5) VALUES (9, ?, 5, ?, 8) ON DUPLICATE KEY"
+            + " UPDATE col2=?",
+        3,
+        new String[] {
+          "INSERT INTO TABLE(col1,col2,col3,col4, col5) VALUES (9, ",
+          ", 5, ",
+          ", 8) ON DUPLICATE KEY UPDATE col2=",
+          ""
+        });
+  }
+
+  @Test
+  public void testRewritableMultipleInserts() throws Exception {
+    checkParsing(
+        "INSERT INTO TABLE(col1,col2) VALUES (?, ?), (?, ?)",
+        4,
+        new String[] {"INSERT INTO TABLE(col1,col2) VALUES (", ", ", "), (", ", ", ")"});
+  }
+
+  @Test
+  public void testCall() throws Exception {
+    checkParsing("CALL dsdssd(?,?)", 2, new String[] {"CALL dsdssd(", ",", ")"});
+  }
+
+  @Test
+  public void testUpdate() throws Exception {
+    checkParsing(
+        "UPDATE MultiTestt4 SET test = ? WHERE test = ?",
+        2,
+        new String[] {"UPDATE MultiTestt4 SET test = ", " WHERE test = ", ""});
+  }
+
+  @Test
+  public void testInsertSelect() throws Exception {
+    checkParsing(
+        "insert into test_insert_select ( field1) (select  TMP.field1 from "
+            + "(select CAST(? as binary) `field1` from dual) TMP)",
+        1,
+        new String[] {
+          "insert into test_insert_select ( field1) (select  TMP.field1 from (select CAST(",
+          " as binary) `field1` from dual) TMP)"
+        });
+  }
+
+  @Test
+  public void testWithoutParameter() throws Exception {
+    checkParsing("SELECT testFunction()", 0, new String[] {"SELECT testFunction()"});
+  }
+
+  @Test
+  public void testWithoutParameterAndParenthesis() throws Exception {
+    checkParsing("SELECT 1", 0, new String[] {"SELECT 1"});
+  }
+
+  @Test
+  public void testWithoutParameterAndValues() throws Exception {
+    checkParsing("INSERT INTO tt VALUES (1)", 0, new String[] {"INSERT INTO tt VALUES (1)"});
+  }
+
+  @Test
+  public void testSemiColon() throws Exception {
+    checkParsing(
+        "INSERT INTO tt (tt) VALUES (?); INSERT INTO tt (tt) VALUES ('multiple')",
+        1,
+        new String[] {
+          "INSERT INTO tt (tt) VALUES (", "); INSERT INTO tt (tt) VALUES ('multiple')"
+        });
+  }
+
+  @Test
+  public void testSemicolonRewritableIfAtEnd() throws Exception {
+    checkParsing(
+        "INSERT INTO table (column1) VALUES (?); ",
+        1,
+        new String[] {"INSERT INTO table (column1) VALUES (", "); "});
+  }
+
+  @Test
+  public void testSemicolonNotRewritableIfNotAtEnd() throws Exception {
+    checkParsing(
+        "INSERT INTO table (column1) VALUES (?); SELECT 1",
+        1,
+        new String[] {"INSERT INTO table (column1) VALUES (", "); SELECT 1"});
+  }
+
+  @Test
+  public void testError() throws Exception {
+    checkParsing(
+        "INSERT INTO tt (tt) VALUES (?); INSERT INTO tt (tt) VALUES ('multiple')",
+        1,
+        new String[] {
+          "INSERT INTO tt (tt) VALUES (", "); INSERT INTO tt (tt) VALUES ('multiple')"
+        });
+  }
+
+  @Test
+  public void testLineComment() throws Exception {
+    checkParsing(
+        "INSERT INTO tt (tt) VALUES (?) --fin",
+        1,
+        new String[] {"INSERT INTO tt (tt) VALUES (", ") --fin"});
+  }
+
+  @Test
+  public void testLineCommentFinished() throws Exception {
+    checkParsing(
+        "INSERT INTO tt (tt) VALUES --fin\n (?)",
+        1,
+        new String[] {"INSERT INTO tt (tt) VALUES --fin\n (", ")"});
+  }
+
+  @Test
+  public void testSelect1() throws Exception {
+    checkParsing("SELECT 1", 0, new String[] {"SELECT 1"});
+  }
+
+  @Test
+  public void rewriteBatchedError() throws Exception {
+    try (Connection connection =
+        createCon("&rewriteBatchedStatements=true&dumpQueriesOnException")) {
+      PreparedStatement preparedStatement =
+          connection.prepareStatement("INSERT INTO errorTable (a, b) VALUES (?, ?, ?)");
+
+      preparedStatement.setString(1, "1");
+      preparedStatement.setString(2, "2");
+      preparedStatement.setString(3, "3");
+      preparedStatement.addBatch();
+      try {
+        preparedStatement.executeBatch();
+        fail("must have thrown error since parameters are not good");
+      } catch (SQLException e) {
+        assertTrue(
+            e.getCause()
+                .getMessage()
+                .contains("Query is: INSERT INTO errorTable (a, b) VALUES (?, ?, ?)"));
+      }
+    }
+  }
+
+  @Test
+  public void errorException() throws Exception {
+    try (Connection connection = createCon("dumpQueriesOnException")) {
+      ensureErrorException(connection);
+    }
+  }
+
+  private void ensureErrorException(Connection connection) throws SQLException {
+    connection.createStatement().execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement pstmt =
+        connection.prepareStatement("UPDATE unknownTable SET col1 = ?, col2 = 0 WHERE col3 = ?");
+    pstmt.setInt(1, 10);
+    pstmt.setInt(2, 20);
+    pstmt.addBatch();
+    pstmt.setInt(1, 100);
+    pstmt.setInt(2, 200);
+    try {
+      pstmt.executeBatch();
+      fail("Must have thrown error");
+    } catch (SQLException sqle) {
+      assertTrue(
+          sqle.getMessage().contains("doesn't exist")
+              || sqle.getMessage().contains("Relation not found: \"testj\".\"unknownTable\"")
+              || sqle.getMessage().contains("Unknown prepared statement handler"),
+          sqle.getMessage());
+      assertTrue(
+          sqle.getMessage()
+              .contains("Query is: UPDATE unknownTable SET col1 = ?, col2 = 0 WHERE col3 = ?"),
+          sqle.getMessage());
+    }
+  }
+
+  @Test
+  public void testLastInsertId() throws Exception {
+    checkParsing(
+        "INSERT INTO tt (tt, tt2) VALUES (LAST_INSERT_ID(), ?)",
+        1,
+        new String[] {"INSERT INTO tt (tt, tt2) VALUES (LAST_INSERT_ID(), ", ")"});
+  }
+
+  @Test
+  public void testValuesForPartition() throws Exception {
+    checkParsing(
+        "ALTER table test_partitioning PARTITION BY RANGE COLUMNS( created_at ) "
+            + "(PARTITION test_p201605 VALUES LESS THAN ('2016-06-01'))",
+        0,
+        new String[] {
+          "ALTER table test_partitioning PARTITION BY RANGE COLUMNS( created_at ) "
+              + "(PARTITION test_p201605 VALUES LESS THAN ('2016-06-01'))"
+        });
+  }
+
+  @Test
+  public void testParse() throws Exception {
+    checkParsing(
+        "INSERT INTO `myTable` VALUES ('\\n"
+            + "\"\\'', \"'\\\n"
+            + "\\\"\")  \n"
+            + " // comment\n"
+            + " , ('a', 'b') # EOL comment",
+        0,
+        new String[] {
+          "INSERT INTO `myTable` VALUES ('\\n"
+              + "\"\\'', \"'\\\n"
+              + "\\\"\")  \n"
+              + " // comment\n"
+              + " , ('a', 'b') # EOL comment"
+        });
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ClobTest.java b/src/test/java/org/mariadb/jdbc/integration/ClobTest.java
new file mode 100644
index 0000000..193beeb
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ClobTest.java
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.sql.Clob;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbClob;
+
+public class ClobTest extends Common {
+
+  private final byte[] bytes = "abc£de🙏fgh".getBytes(StandardCharsets.UTF_8);
+
+  @Test
+  public void length() {
+    MariaDbClob clob = new MariaDbClob(bytes);
+    assertEquals(11, clob.length());
+
+    MariaDbClob clob2 = new MariaDbClob(bytes, 2, 3);
+    assertEquals(2, clob2.length());
+  }
+
+  @Test
+  public void getSubString() throws SQLException {
+    MariaDbClob clob = new MariaDbClob(bytes);
+    assertEquals("abc£de🙏", clob.getSubString(1, 8));
+    assertEquals("abc£de🙏fgh", clob.getSubString(1, 21));
+    assertEquals("abc£de🙏fgh", clob.getSubString(1, (int) clob.length()));
+    assertEquals("ab", clob.getSubString(1, 2));
+    assertEquals("🙏", clob.getSubString(7, 2));
+
+    MariaDbClob clob2 = new MariaDbClob(bytes, 6, 6);
+
+    assertEquals("e🙏f", clob2.getSubString(1, 20));
+    assertEquals("🙏f", clob2.getSubString(2, 3));
+
+    try {
+      clob2.getSubString(0, 3);
+      fail("must have thrown exception, min pos is 1");
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    MariaDbClob clob = new MariaDbClob(bytes);
+    assureReaderEqual("abc£de🙏", clob.getCharacterStream(1, 8));
+    assureReaderEqual("abc£de🙏fgh", clob.getCharacterStream(1, 11));
+    try {
+      assureReaderEqual("abc£de🙏fgh", clob.getCharacterStream(1, 20));
+      fail("must have throw exception, length > to number of characters");
+    } catch (SQLException sqle) {
+      // normal error
+    }
+    assureReaderEqual("bc£de🙏", clob.getCharacterStream(2, 7));
+
+    MariaDbClob clob2 = new MariaDbClob(bytes, 2, 9);
+    assureReaderEqual("c£de🙏", clob2.getCharacterStream(1, 6));
+    try {
+      assureReaderEqual("c£de🙏fg", clob2.getCharacterStream(1, 20));
+      fail("must have throw exception, length > to number of characters");
+    } catch (SQLException sqle) {
+      // normal error
+    }
+
+    assureReaderEqual("de🙏", clob2.getCharacterStream(3, 4));
+  }
+
+  private void assureReaderEqual(String expectedStr, Reader reader) {
+    try {
+      char[] expected = expectedStr.toCharArray();
+      char[] readArr = new char[expected.length];
+      assertEquals(expected.length, reader.read(readArr));
+      assertArrayEquals(expected, readArr);
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+      fail();
+    }
+  }
+
+  @Test
+  public void setCharacterStream() throws SQLException, IOException {
+    final byte[] bytes = "abcde🙏fgh".getBytes(StandardCharsets.UTF_8);
+    MariaDbClob clob = new MariaDbClob(bytes);
+    assureReaderEqual("abcde🙏", clob.getCharacterStream(1, 7));
+
+    Writer writer = clob.setCharacterStream(2);
+    writer.write("tuvxyz", 2, 3);
+    writer.flush();
+    assertEquals("avxye🙏", clob.getSubString(1, 7));
+
+    clob = new MariaDbClob(bytes);
+
+    writer = clob.setCharacterStream(2);
+    writer.write("1234567890lmnopqrstu", 1, 19);
+    writer.flush();
+    assertEquals("a234567890lmnopqrstu", clob.getSubString(1, 100));
+  }
+
+  @Test
+  public void position() {
+    MariaDbClob clob = new MariaDbClob(bytes);
+    assertEquals(5, clob.position("de", 2));
+    assertEquals(5, clob.position((Clob) new MariaDbClob("de".getBytes()), 2));
+
+    clob = new MariaDbClob(bytes, 2, 10);
+    assertEquals(5, clob.position("🙏", 2));
+  }
+
+  @Test
+  public void setString() throws SQLException {
+    final byte[] bytes = "abcd£e🙏fgh".getBytes(StandardCharsets.UTF_8);
+    final MariaDbClob clob = new MariaDbClob(bytes);
+    assureReaderEqual("abcd£e🙏", clob.getCharacterStream(1, 8));
+    clob.setString(2, "zuv");
+    assertEquals("azuv£e🙏", clob.getSubString(1, 8));
+    clob.setString(9, "zzz");
+    assertEquals("azuv£e🙏fzzz", clob.getSubString(1, 12));
+
+    MariaDbClob clob2 = new MariaDbClob("abcde🙏fgh".getBytes(StandardCharsets.UTF_8), 2, 9);
+    assureReaderEqual("cde🙏fg", clob2.getCharacterStream(1, 7));
+    assertEquals("cde🙏fg", clob2.getSubString(1, 7));
+
+    clob2.setString(2, "zg");
+    assertEquals("czg🙏f", clob2.getSubString(1, 6));
+    clob2.setString(7, "zzz");
+    assertEquals("czg🙏fgzzz", clob2.getSubString(1, 12));
+
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob2.setString(2, "abcd", 2, -2), "len must be > 0");
+    clob2.setString(2, "abcd", 2, 2);
+    assertEquals("ccd🙏f", clob2.getSubString(1, 6));
+    clob2.setString(2, "opml", 3, 200);
+    assertEquals("cld🙏f", clob2.getSubString(1, 6));
+
+    clob2.setString(5, "අข\uD800\uDFA2");
+    assertEquals("cld🙏අข\uD800\uDFA2", clob2.getSubString(1, 20));
+    assertEquals(9, clob2.length());
+    clob2.setString(6, "ข\uD800\uDFA2");
+    assertEquals("cld🙏අข\uD800\uDFA2", clob2.getSubString(1, 20));
+    clob2.setString(7, "\uD800\uDFA2");
+    assertEquals("cld🙏අข\uD800\uDFA2", clob2.getSubString(1, 20));
+    clob2.truncate(9);
+    assertEquals("cld🙏අข\uD800\uDFA2", clob2.getSubString(1, 20));
+    clob2.truncate(7);
+    assertEquals("cld🙏අข", clob2.getSubString(1, 20));
+    clob2.truncate(6);
+    assertEquals("cld🙏අ", clob2.getSubString(1, 20));
+    clob2.truncate(5);
+    assertEquals("cld🙏", clob2.getSubString(1, 20));
+    clob2.truncate(3);
+    assertEquals("cld", clob2.getSubString(1, 20));
+
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob.setString(-1, "7"), "position must be >= 0");
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob.setString(1, null), "cannot add null string");
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob.setString(-1, null, 1, 2), "cannot add null string");
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob.setString(0, "dd", -1, 2), "offset must be >= 0");
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob.getSubString(-1, 7), "position must be >= 1");
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob.getSubString(1, -7), "length must be > 0");
+    Common.assertThrowsContains(
+        SQLException.class, () -> clob.setString(-2, "rrr"), "position must be >= 0");
+  }
+
+  @Test
+  public void setAsciiStream() throws SQLException, IOException {
+    final byte[] bytes = "abcde🙏fgh".getBytes(StandardCharsets.UTF_8);
+    MariaDbClob clob = new MariaDbClob(bytes);
+    assureReaderEqual("abcde🙏", clob.getCharacterStream(1, 7));
+
+    OutputStream stream = clob.setAsciiStream(2);
+    stream.write("tuvxyz".getBytes(), 2, 3);
+    stream.flush();
+
+    assertEquals("avxye🙏", clob.getSubString(1, 7));
+
+    clob = new MariaDbClob(bytes);
+
+    stream = clob.setAsciiStream(2);
+    stream.write("1234567890lmnopqrstu".getBytes(), 1, 19);
+    stream.flush();
+    assertEquals("a234567890lmnopqrstu", clob.getSubString(1, 100));
+
+    MariaDbClob clob2 = new MariaDbClob(bytes);
+    InputStream stream2 = clob2.getAsciiStream();
+    byte[] b = new byte[12];
+    stream2.read(b);
+    assertArrayEquals(bytes, b);
+  }
+
+  @Test
+  public void wrongUtf8() {
+    final byte[] utf8Wrong2bytes = new byte[] {0x08, (byte) 0xFF, (byte) 0x6F, (byte) 0x6F};
+    final byte[] utf8Wrong3bytes =
+        new byte[] {0x07, (byte) 0x0a, (byte) 0xff, (byte) 0x6F, (byte) 0x6F};
+    final byte[] utf8Wrong4bytes =
+        new byte[] {0x10, (byte) 0x20, (byte) 0x0a, (byte) 0xff, (byte) 0x6F, (byte) 0x6F};
+    final byte[] utf8Wrong4bytes2 = new byte[] {-16, (byte) -97, (byte) -103};
+
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(utf8Wrong2bytes).length(),
+        "invalid UTF8");
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(new byte[] {(byte) 225}).length(),
+        "invalid UTF8");
+
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(utf8Wrong3bytes).length(),
+        "invalid UTF8");
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(utf8Wrong4bytes).length(),
+        "invalid UTF8");
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(new byte[] {(byte) 225}).truncate(2),
+        "invalid UTF8");
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(utf8Wrong2bytes).truncate(2),
+        "invalid UTF8");
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(utf8Wrong3bytes).truncate(3),
+        "invalid UTF8");
+    Common.assertThrowsContains(
+        UncheckedIOException.class,
+        () -> new MariaDbClob(utf8Wrong4bytes2).truncate(4),
+        "invalid UTF8");
+  }
+
+  @Test
+  public void setBinaryStream() throws SQLException, IOException {
+    final byte[] otherBytes = new byte[] {10, 11, 12, 13};
+
+    MariaDbClob blob = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out = blob.setBinaryStream(2);
+    out.write(otherBytes);
+    assertArrayEquals(new byte[] {0, 10, 11, 12, 13, 5}, blob.getBytes(1, 6));
+
+    MariaDbClob blob2 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out2 = blob2.setBinaryStream(4);
+    out2.write(otherBytes);
+    assertArrayEquals(new byte[] {0, 1, 2, 10, 11, 12, 13}, blob2.getBytes(1, 7));
+
+    MariaDbClob blob3 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out3 = blob3.setBinaryStream(2);
+    out3.write(otherBytes);
+    assertArrayEquals(new byte[] {2, 10, 11, 12, 13, 0, 0}, blob3.getBytes(1, 7));
+
+    MariaDbClob blob4 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out4 = blob4.setBinaryStream(4);
+    out4.write(otherBytes);
+    assertArrayEquals(new byte[] {2, 3, 4, 10, 11, 12}, blob4.getBytes(1, 6));
+
+    try {
+      MariaDbClob blob5 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+      blob5.setBinaryStream(0);
+    } catch (SQLException sqle) {
+      // normal exception
+    }
+  }
+
+  @Test
+  public void setBinaryStreamOffset() throws SQLException, IOException {
+    final byte[] otherBytes = new byte[] {10, 11, 12, 13};
+
+    MariaDbClob blob = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out = blob.setBinaryStream(2);
+    out.write(otherBytes, 2, 3);
+    assertArrayEquals(new byte[] {0, 12, 13, 3, 4, 5}, blob.getBytes(1, 6));
+
+    MariaDbClob blob2 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5});
+    OutputStream out2 = blob2.setBinaryStream(4);
+    out2.write(otherBytes, 3, 2);
+    assertArrayEquals(new byte[] {0, 1, 2, 13, 4, 5, 0}, blob2.getBytes(1, 7));
+
+    MariaDbClob blob3 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 4);
+    OutputStream out3 = blob3.setBinaryStream(2);
+    out3.write(otherBytes, 2, 3);
+    assertArrayEquals(new byte[] {2, 12, 13, 5, 0, 0, 0}, blob3.getBytes(1, 7));
+
+    MariaDbClob blob4 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out4 = blob4.setBinaryStream(4);
+    out4.write(otherBytes, 2, 2);
+    assertArrayEquals(new byte[] {2, 3, 4, 12, 13, 0}, blob4.getBytes(1, 6));
+
+    MariaDbClob blob5 = new MariaDbClob(new byte[] {0, 1, 2, 3, 4, 5}, 2, 3);
+    OutputStream out5 = blob5.setBinaryStream(4);
+    out5.write(otherBytes, 2, 20);
+    assertArrayEquals(new byte[] {2, 3, 4, 12, 13, 0}, blob5.getBytes(1, 6));
+  }
+
+  @Test
+  public void truncate() throws SQLException {
+    MariaDbClob clob = new MariaDbClob(bytes);
+    clob.truncate(20);
+    assertEquals("abc£de🙏f", clob.getSubString(1, 9));
+    clob.truncate(8);
+    assertEquals("abc£de🙏", clob.getSubString(1, 9));
+    assertEquals("abc£de🙏", clob.getSubString(1, 8));
+    clob.truncate(7);
+    assertEquals("abc£de�", clob.getSubString(1, 9));
+    clob.truncate(6);
+    assertEquals("abc£de", clob.getSubString(1, 9));
+    clob.truncate(4);
+    assertEquals("abc£", clob.getSubString(1, 8));
+    clob.truncate(3);
+    assertEquals("abc", clob.getSubString(1, 8));
+    clob.truncate(0);
+    assertEquals("", clob.getSubString(1, 8));
+
+    MariaDbClob clob2 = new MariaDbClob("abc£de🙏fgh".getBytes(StandardCharsets.UTF_8), 2, 10);
+    clob2.truncate(20);
+    assertEquals("c£de🙏f", clob2.getSubString(1, 9));
+    clob2.truncate(6);
+    assertEquals("c£de🙏", clob2.getSubString(1, 9));
+    clob2.truncate(5);
+    assertEquals("c£de�", clob2.getSubString(1, 9));
+    clob2.truncate(4);
+    assertEquals("c£de", clob2.getSubString(1, 9));
+    clob2.truncate(0);
+    assertEquals("", clob2.getSubString(1, 7));
+  }
+
+  @Test
+  public void free() {
+    MariaDbClob blob = new MariaDbClob(bytes);
+    blob.free();
+    assertEquals(0, blob.length());
+  }
+
+  @Test
+  @SuppressWarnings("checkstyle:AvoidEscapedUnicodeCharacters")
+  public void clobLength() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    try (ResultSet rs =
+        stmt.executeQuery("SELECT 'ab$c', 'ab¢c', 'abहc', 'ab\uD801\uDC37c', 'ab𐍈c' from dual")) {
+      while (rs.next()) {
+
+        Clob clob1 = rs.getClob(1);
+        assertEquals(4, clob1.length());
+
+        Clob clob2 = rs.getClob(2);
+        assertEquals(4, clob2.length());
+
+        Clob clob3 = rs.getClob(3);
+        assertEquals(4, clob3.length());
+
+        Clob clob4 = rs.getClob(4);
+        assertEquals(5, clob4.length());
+
+        Clob clob5 = rs.getClob(5);
+        assertEquals(5, clob5.length());
+
+        clob1.truncate(3);
+        clob2.truncate(3);
+        clob3.truncate(3);
+        clob4.truncate(3);
+        clob5.truncate(3);
+
+        assertEquals(3, clob1.length());
+        assertEquals(3, clob2.length());
+        assertEquals(3, clob3.length());
+        assertEquals(3, clob4.length());
+        assertEquals(3, clob5.length());
+
+        assertEquals("ab$", clob1.getSubString(1, 3));
+        assertEquals("ab¢", clob2.getSubString(1, 3));
+        assertEquals("abह", clob3.getSubString(1, 3));
+        assertEquals("ab�", clob4.getSubString(1, 3));
+        assertEquals("ab�", clob5.getSubString(1, 3));
+      }
+    }
+  }
+
+  @Test
+  public void equal() {
+    MariaDbClob clob = new MariaDbClob(bytes);
+    assertEquals(clob, clob);
+    assertEquals(new MariaDbClob(bytes), clob);
+    assertFalse(clob.equals(null));
+    assertFalse(clob.equals(""));
+    byte[] bytes = "Abc£de🙏fgh".getBytes(StandardCharsets.UTF_8);
+    assertNotEquals(new MariaDbClob(bytes), clob);
+    assertNotEquals(new MariaDbClob("Abc".getBytes(StandardCharsets.UTF_8)), clob);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/Common.java b/src/test/java/org/mariadb/jdbc/integration/Common.java
new file mode 100644
index 0000000..b0003e8
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/Common.java
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.Properties;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.extension.*;
+import org.junit.jupiter.api.function.Executable;
+import org.mariadb.jdbc.*;
+import org.mariadb.jdbc.export.HaMode;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.integration.tools.TcpProxy;
+
+public class Common {
+
+  public static Connection sharedConn;
+  public static Connection sharedConnBinary;
+  public static String hostname;
+  public static int port;
+  public static String user;
+  public static String password;
+  public static String database;
+  public static String defaultOther;
+  public static TcpProxy proxy;
+  public static String mDefUrl;
+  private static Instant initialTest;
+
+  static {
+    try (InputStream inputStream =
+        Common.class.getClassLoader().getResourceAsStream("conf.properties")) {
+      Properties prop = new Properties();
+      prop.load(inputStream);
+      String val = System.getenv("TEST_REQUIRE_TLS");
+      if ("1".equals(val)) {
+        String cert = System.getenv("TEST_DB_SERVER_CERT");
+        defaultOther = "&sslMode=verify-full&serverSslCert=" + cert;
+      } else {
+        defaultOther = get("DB_OTHER", prop);
+      }
+      hostname = get("DB_HOST", prop);
+      user = get("DB_USER", prop);
+      port = Integer.parseInt(get("DB_PORT", prop));
+      password = get("DB_PASSWORD", prop);
+      database = get("DB_DATABASE", prop);
+      mDefUrl =
+          password == null || password.isEmpty()
+              ? String.format(
+                  "jdbc:mariadb://%s:%s/%s?user=%s%s", hostname, port, database, user, defaultOther)
+              : String.format(
+                  "jdbc:mariadb://%s:%s/%s?user=%s&password=%s%s",
+                  hostname, port, database, user, password, defaultOther);
+
+    } catch (IOException io) {
+      io.printStackTrace();
+    }
+  }
+
+  private static String get(String name, Properties prop) {
+    String val = System.getenv("TEST_" + name);
+    if (val == null) val = System.getProperty("TEST_" + name);
+    if (val == null) val = prop.getProperty(name);
+    return val;
+  }
+
+  @BeforeAll
+  public static void beforeAll() throws Exception {
+    sharedConn = (Connection) DriverManager.getConnection(mDefUrl);
+    String binUrl = mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "useServerPrepStmts=true";
+    sharedConnBinary = (Connection) DriverManager.getConnection(binUrl);
+  }
+
+  @AfterAll
+  public static void afterEAll() throws SQLException {
+    if (sharedConn != null) {
+      sharedConn.close();
+      sharedConnBinary.close();
+    }
+    if (proxy != null) {
+      proxy.forceClose();
+    }
+  }
+
+  public static boolean isMariaDBServer() {
+    return sharedConn.getContext().getVersion().isMariaDBServer();
+  }
+
+  public static boolean hasCapability(long capability) {
+    return sharedConn.getContext().hasClientCapability(capability);
+  }
+
+  public static boolean runLongTest() {
+    String runLongTest = System.getenv("RUN_LONG_TEST");
+    if (runLongTest != null) {
+      return Boolean.parseBoolean(runLongTest);
+    }
+    return false;
+  }
+
+  public static boolean isXpand() {
+    String srv = System.getenv("srv");
+    if (srv != null) {
+      return "xpand".equals(srv);
+    }
+    return sharedConn.getContext().getVersion().isMariaDBServer()
+        && sharedConn.getContext().getVersion().getQualifier().toLowerCase().contains("xpand");
+  }
+
+  public static boolean minVersion(int major, int minor, int patch) {
+    return sharedConn.getContext().getVersion().versionGreaterOrEqual(major, minor, patch);
+  }
+
+  public static boolean exactVersion(int major, int minor, int patch) {
+    return sharedConn.getContext().getVersion().getMajorVersion() == major
+        && sharedConn.getContext().getVersion().getMinorVersion() == minor
+        && sharedConn.getContext().getVersion().getPatchVersion() == patch;
+  }
+
+  public static Connection createCon() throws SQLException {
+    return (Connection) DriverManager.getConnection(mDefUrl);
+  }
+
+  public static void createSequenceTables() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    boolean seq10_ok = false;
+    boolean seq10_000_ok = false;
+    try {
+      ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM sequence_1_to_10");
+      if (rs.next() && rs.getInt(1) == 10) {
+        seq10_ok = true;
+      }
+    } catch (SQLException e) {
+      // eat
+    }
+    if (!seq10_ok) {
+      stmt.execute("DROP TABLE IF EXISTS sequence_1_to_10");
+      stmt.execute("CREATE TABLE sequence_1_to_10 (t1 int)");
+      stmt.execute("insert into sequence_1_to_10 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)");
+    }
+
+    try {
+      ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM sequence_1_to_10000");
+      if (rs.next() && rs.getInt(1) == 10_000) {
+        seq10_000_ok = true;
+      }
+    } catch (SQLException e) {
+      // eat
+    }
+    if (!seq10_000_ok) {
+      stmt.execute("DROP TABLE IF EXISTS sequence_1_to_10000");
+      stmt.execute("CREATE TABLE sequence_1_to_10000 (t1 int)");
+      try (PreparedStatement prep =
+          sharedConnBinary.prepareStatement("INSERT INTO sequence_1_to_10000 VALUES (?)")) {
+        for (int i = 1; i <= 10_000; i++) {
+          prep.setInt(1, i);
+          prep.addBatch();
+        }
+        prep.executeBatch();
+      }
+    }
+  }
+
+  public Connection createProxyCon(HaMode mode, String opts) throws SQLException {
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try {
+      proxy = new TcpProxy(hostAddress.host, hostAddress.port);
+    } catch (IOException i) {
+      throw new SQLException("proxy error", i);
+    }
+
+    String url = mDefUrl.replaceAll("//([^/]*)/", "//localhost:" + proxy.getLocalPort() + "/");
+    if (mode != HaMode.NONE) {
+      url =
+          url.replaceAll(
+              "jdbc:mariadb:", "jdbc:mariadb:" + mode.name().toLowerCase(Locale.ROOT) + ":");
+    }
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    return (Connection) DriverManager.getConnection(url + opts);
+  }
+
+  public static boolean haveSsl() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("show variables like '%ssl%'");
+    //    while (rs.next()) {
+    //      System.out.println(rs.getString(1) + ":" + rs.getString(2));
+    //    }
+    try {
+      rs = stmt.executeQuery("select @@have_ssl");
+      assertTrue(rs.next());
+      return "YES".equals(rs.getString(1));
+    } catch (SQLException e) {
+      return false;
+    }
+  }
+
+  public boolean isWindows() {
+    return System.getProperty("os.name").toLowerCase().contains("win");
+  }
+
+  public void cancelForVersion(int major, int minor) {
+    String dbVersion = sharedConn.getMetaData().getDatabaseProductVersion();
+    Assumptions.assumeFalse(dbVersion.startsWith(major + "." + minor));
+  }
+
+  public static Connection createCon(String option) throws SQLException {
+    return (Connection) DriverManager.getConnection(mDefUrl + "&" + option);
+  }
+
+  public static Connection createCon(String option, Integer sslPort) throws SQLException {
+    Configuration conf = Configuration.parse(mDefUrl + "&" + option);
+    if (sslPort != null) {
+      for (HostAddress hostAddress : conf.addresses()) {
+        hostAddress.port = sslPort;
+      }
+    }
+    return Driver.connect(conf);
+  }
+
+  @AfterEach
+  public void afterEach1() throws SQLException {
+    sharedConn.isValid(2000);
+    sharedConnBinary.isValid(2000);
+  }
+
+  public static int getMaxAllowedPacket() throws SQLException {
+    java.sql.Statement st = sharedConn.createStatement();
+    ResultSet rs = st.executeQuery("select @@max_allowed_packet");
+    assertTrue(rs.next());
+    return rs.getInt(1);
+  }
+
+  public static void assertThrowsContains(
+      Class<? extends Exception> expectedType, Executable executable, String expected) {
+    Exception e = Assertions.assertThrows(expectedType, executable);
+    Assertions.assertTrue(e.getMessage().contains(expected), "real message:" + e.getMessage());
+  }
+
+  @RegisterExtension public Extension watcher = new Follow();
+
+  private static class Follow implements TestWatcher, BeforeEachCallback {
+    @Override
+    public void testDisabled(ExtensionContext context, Optional<String> reason) {
+      System.out.printf(
+          "  - Disabled %s: with reason :- %s%n",
+          context.getDisplayName(), reason.orElse("No reason"));
+    }
+
+    @Override
+    public void testAborted(ExtensionContext context, Throwable cause) {
+      System.out.printf("  - Aborted %s: %n", context.getDisplayName());
+    }
+
+    @Override
+    public void testFailed(ExtensionContext context, Throwable cause) {
+      System.out.printf("  ✗ Failed %s: %n", context.getDisplayName());
+    }
+
+    @Override
+    public void testSuccessful(ExtensionContext context) {
+      System.out.printf(
+          "  ✓ %s: %sms%n",
+          context.getDisplayName(), Duration.between(initialTest, Instant.now()).toMillis());
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext extensionContext) {
+      initialTest = Instant.now();
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/CompressTest.java b/src/test/java/org/mariadb/jdbc/integration/CompressTest.java
new file mode 100644
index 0000000..9fcbf5d
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/CompressTest.java
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+
+public class CompressTest extends Common {
+  private static Connection shareCompressCon;
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS compressTest");
+    stmt.execute(
+        "CREATE TABLE compressTest (t1 int not null primary key auto_increment, "
+            + "t2 LONGTEXT, t3 LONGTEXT, t4 LONGTEXT, t5 LONGTEXT, t6 LONGTEXT)");
+    shareCompressCon = createCon("useCompression=true");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE IF EXISTS compressTest");
+    shareCompressCon.close();
+  }
+
+  @Test
+  public void bigSend() throws SQLException {
+    int[] maxSize = new int[] {8 * 1024, 128 * 1024, 1024 * 1024, 16 * 1024 * 1024};
+
+    for (int i = 0; i < maxSize.length; i++) {
+      bigSend(sharedConn, maxSize[i]);
+      bigSend(sharedConnBinary, maxSize[i]);
+      bigSend(shareCompressCon, maxSize[i]);
+    }
+  }
+
+  public void bigSend(Connection con, int maxLen) throws SQLException {
+    int maxAllowed = getMaxAllowedPacket();
+    Assumptions.assumeTrue(maxAllowed > 16 * 1024 * 1024);
+    char[] arr2 = new char[Math.min(maxLen, Math.min(16 * 1024 * 1024, (maxAllowed / 2) - 1000))];
+    for (int pos = 0; pos < arr2.length; pos++) {
+      arr2[pos] = (char) ('A' + (pos % 60));
+    }
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE compressTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    String st2 = new String(arr2, 0, 5_000);
+    String st3 = new String(arr2, 0, Math.min(maxLen, 150_000));
+    String st4 = new String(arr2, 0, Math.min(maxLen, 1_100_000));
+    String st5 = new String(arr2, 0, Math.min(maxLen, 1_100_000));
+    String st6 = new String(arr2);
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO compressTest VALUES (?, ?, ?, ?, ?, ?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, st2);
+      prep.setString(3, st3);
+      prep.setString(4, st4);
+      prep.setString(5, st5);
+      prep.setString(6, st6);
+      prep.execute();
+
+      prep.setInt(1, 2);
+      prep.setString(2, st2);
+      prep.setString(3, st3);
+      prep.setString(4, st4);
+      prep.setString(5, st5);
+      prep.setString(6, st6);
+      prep.execute();
+    }
+    stmt.setFetchSize(1);
+    ResultSet rs = stmt.executeQuery("SELECT * from compressTest");
+    assertTrue(rs.next());
+
+    assertEquals(st2, rs.getString(2));
+    assertEquals(st3, rs.getString(3));
+    assertEquals(st4, rs.getString(4));
+    assertEquals(st5, rs.getString(5));
+    assertEquals(st6, rs.getString(6));
+    rs.close();
+    stmt.execute("COMMIT");
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ConfigurationTest.java b/src/test/java/org/mariadb/jdbc/integration/ConfigurationTest.java
new file mode 100644
index 0000000..afbd5c5
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ConfigurationTest.java
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class ConfigurationTest extends Common {
+
+  @BeforeAll
+  public static void begin() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE testSessionVariable(id int not null primary key auto_increment, test"
+            + " varchar(10))");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS testSessionVariable");
+  }
+
+  @Test
+  public void testSessionVariable() throws SQLException {
+    try (Connection connection =
+        createCon("sessionVariables=auto_increment_increment=2&allowMultiQueries=true")) {
+      Statement stmt = connection.createStatement();
+      stmt.execute(
+          "INSERT INTO testSessionVariable (test) values ('bb'),('cc');"
+              + "INSERT INTO testSessionVariable (test) values ('dd'),('ee')",
+          Statement.RETURN_GENERATED_KEYS);
+
+      ResultSet rs = stmt.getGeneratedKeys();
+
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt(1));
+      assertTrue(rs.next());
+      if (!"galera".equals(System.getenv("srv"))) {
+        assertEquals(5, rs.getInt(1));
+      }
+      assertFalse(rs.next());
+      assertFalse(stmt.getMoreResults());
+      rs.clearWarnings();
+    }
+
+    // Xpand doesn't support session_track_system_variables
+    if (!isXpand()) {
+      try (Connection connection =
+          createCon("sessionVariables=session_track_system_variables='some\\';f,\"ff'")) {
+        Statement stmt = connection.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT @@session_track_system_variables");
+        assertTrue(rs.next());
+      }
+      try (Connection connection =
+          createCon("sessionVariables=session_track_system_variables=\"some\\\";f,'ff'\"")) {
+        Statement stmt = connection.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT @@session_track_system_variables");
+        assertTrue(rs.next());
+      }
+    }
+  }
+
+  @Test
+  public void connectionAttributes() throws SQLException {
+    // xpand doesn't support @@performance_schema variable
+    Assumptions.assumeTrue(!"maxscale".equals(System.getenv("srv")) && !isXpand());
+
+    try (org.mariadb.jdbc.Connection conn =
+        createCon("&connectionAttributes=test:test1,test2:test2Val,test3")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs1 = stmt.executeQuery("SELECT @@performance_schema");
+      rs1.next();
+      Assumptions.assumeTrue("1".equals(rs1.getString(1)));
+
+      ResultSet rs =
+          stmt.executeQuery(
+              "SELECT * from performance_schema.session_connect_attrs where processlist_id="
+                  + conn.getThreadId()
+                  + " AND ATTR_NAME like 'test%'");
+      assertTrue(rs.next());
+      assertEquals("test1", rs.getString("ATTR_VALUE"));
+      assertTrue(rs.next());
+      assertEquals("test2Val", rs.getString("ATTR_VALUE"));
+      assertTrue(rs.next());
+      assertNull(rs.getString("ATTR_VALUE"));
+    }
+  }
+
+  @Test
+  public void useMysqlMetadata() throws SQLException {
+    assertEquals(
+        isMariaDBServer() ? "MariaDB" : "MySQL", sharedConn.getMetaData().getDatabaseProductName());
+    try (org.mariadb.jdbc.Connection conn = createCon("&useMysqlMetadata=true")) {
+      assertEquals("MySQL", conn.getMetaData().getDatabaseProductName());
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ConnectionTest.java b/src/test/java/org/mariadb/jdbc/integration/ConnectionTest.java
new file mode 100644
index 0000000..5541946
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ConnectionTest.java
@@ -0,0 +1,1194 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.Executor;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.*;
+import org.mariadb.jdbc.integration.util.SocketFactoryBasicTest;
+import org.mariadb.jdbc.integration.util.SocketFactoryTest;
+
+@DisplayName("Connection Test")
+public class ConnectionTest extends Common {
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    createSequenceTables();
+  }
+
+  @Test
+  public void isValid() throws SQLException {
+    Connection sharedConn = DriverManager.getConnection(mDefUrl);
+    assertTrue(sharedConn.isValid(2000));
+    sharedConn.close();
+    assertFalse(sharedConn.isValid(2000));
+  }
+
+  @Test
+  public void tcpKeepAlive() throws SQLException {
+    try (Connection con = createCon("&tcpKeepAlive=false")) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  void isValidWrongValue() {
+    try {
+      sharedConn.isValid(-2000);
+      fail("most have thrown an error");
+    } catch (SQLException e) {
+      assertTrue(e.getMessage().contains("the value supplied for timeout is negative"));
+    }
+  }
+
+  @Test
+  void missingHost() {
+    assertThrowsContains(
+        SQLException.class,
+        () -> DriverManager.getConnection("jdbc:mariadb:///db"),
+        "hostname must be set to connect socket if not using local socket or pipe");
+    assertThrowsContains(
+        SQLException.class,
+        () -> DriverManager.getConnection("jdbc:mariadb:///db?socketFactory=test"),
+        "hostname must be set to connect socket");
+  }
+
+  @Test
+  void socketTimeout() throws SQLException {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !isXpand());
+
+    try (Connection con = createCon("&socketTimeout=50")) {
+      assertEquals(50, con.getNetworkTimeout());
+      Statement stmt = con.createStatement();
+      stmt.execute("SELECT 1");
+      Common.assertThrowsContains(SQLException.class, () -> stmt.execute("SELECT SLEEP(0.1)"), "");
+    }
+
+    try (Connection con = createCon("&socketTimeout=500")) {
+      assertEquals(500, con.getNetworkTimeout());
+      Statement stmt = con.createStatement();
+      stmt.execute("SELECT SLEEP(0.1)");
+      Common.assertThrowsContains(SQLException.class, () -> stmt.execute("SELECT SLEEP(1)"), "");
+    }
+
+    try (Connection con = createCon("&socketTimeout=0")) {
+      assertEquals(0, con.getNetworkTimeout());
+      Statement stmt = con.createStatement();
+      stmt.execute("SELECT SLEEP(0.5)");
+    }
+  }
+
+  @Test
+  public void autoCommit() throws SQLException {
+    Connection con = DriverManager.getConnection(mDefUrl);
+    assertTrue(con.getAutoCommit());
+    con.setAutoCommit(false);
+    assertFalse(con.getAutoCommit());
+    con.setAutoCommit(false);
+    assertFalse(con.getAutoCommit());
+    con.setAutoCommit(true);
+    assertTrue(con.getAutoCommit());
+    con.setAutoCommit(true);
+    assertTrue(con.getAutoCommit());
+    Statement stmt = con.createStatement();
+    stmt.execute("SET autocommit=false");
+    assertFalse(con.getAutoCommit());
+    con.close();
+  }
+
+  @Test
+  public void initSQL() throws SQLException {
+    try (Connection con = createCon("&initSql=SET @myVar='YourVar'")) {
+      Statement stmt = con.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT @myVar");
+      assertTrue(rs.next());
+      assertEquals("YourVar", rs.getString(1));
+    }
+  }
+
+  @Test
+  public void nativeSQL() throws SQLException {
+    String[] inputs =
+        new String[] {
+          "select {fn TIMESTAMPDIFF ( SQL_TSI_HOUR, {fn convert('SQL_', SQL_INTEGER)})}, {fn"
+              + " TIMESTAMPDIFF (HOUR, {fn convert  ('sQL_'   , SQL_INTEGER)})}",
+          "{call foo({fn now()})} //end",
+          "{call foo({fn '{' now()} /* {test}# \"'\" */) \"\\\"'#\" '\"\\''} #{test2}",
+          "{  call foo({fn now()})}",
+          "{\r\ncall foo({fn now()})}",
+          "{\r\n  call foo({fn now()})}",
+          "{call foo(/*{fn now()}*/)}",
+          "{CALL foo({fn now() /* -- * */ -- test \n })}",
+          "{?=call foo({fn now()})}",
+          "SELECT 'David_' LIKE 'David|_' {escape '|'}",
+          "select {fn dayname ({fn abs({fn now()})})}",
+          "{d '1997-05-24'}",
+          "{d'1997-05-24'}",
+          "{\nt'10:30:29'}",
+          "{t '10:30:29'}",
+          "{t'10:30:29'}",
+          "{ts '1997-05-24 10:30:29.123'}",
+          "{ts'1997-05-24 10:30:29.123'}",
+          "'{string data with { or } will not be altered'",
+          "`{string data with { or } will not be altered`",
+          "--  Also note that you can safely include { and } in comments",
+          "SELECT * FROM {oj TABLE1 LEFT OUTER JOIN TABLE2 ON DEPT_NO = 003420930}"
+        };
+    String[] outputs =
+        new String[] {
+          "select TIMESTAMPDIFF ( HOUR, convert('SQL_', INTEGER)), TIMESTAMPDIFF (HOUR, convert "
+              + " ('sQL_'   , INTEGER))",
+          "call foo(now()) //end",
+          "call foo('{' now() /* {test}# \"'\" */) \"\\\"'#\" '\"\\'' #{test2}",
+          "call foo(now())",
+          "call foo(now())",
+          "call foo(now())",
+          "call foo(/*{fn now()}*/)",
+          "CALL foo(now() /* -- * */ -- test \n )",
+          "?=call foo(now())",
+          "SELECT 'David_' LIKE 'David|_' escape '|'",
+          "select dayname (abs(now()))",
+          "'1997-05-24'",
+          "'1997-05-24'",
+          "'10:30:29'",
+          "'10:30:29'",
+          "'10:30:29'",
+          "'1997-05-24 10:30:29.123'",
+          "'1997-05-24 10:30:29.123'",
+          "'{string data with { or } will not be altered'",
+          "`{string data with { or } will not be altered`",
+          "--  Also note that you can safely include { and } in comments",
+          "SELECT * FROM TABLE1 LEFT OUTER JOIN TABLE2 ON DEPT_NO = 003420930"
+        };
+    for (int i = 0; i < inputs.length; i++) {
+      assertEquals(outputs[i], sharedConn.nativeSQL(inputs[i]));
+    }
+    assertEquals(
+        "INSERT INTO TEST_SYNTAX_ERROR(str_value, json_value) VALUES ('abc\\\\', '{\"data\":"
+            + " \"test\"}')",
+        sharedConn.nativeSQL(
+            "INSERT INTO TEST_SYNTAX_ERROR(str_value, json_value) VALUES ('abc\\\\', '{\"data\":"
+                + " \"test\"}')"));
+
+    try {
+      sharedConn.nativeSQL("{call foo({fn now())}");
+      fail("most have thrown an error");
+    } catch (SQLException e) {
+      assertTrue(
+          e.getMessage().contains("Invalid escape sequence , missing closing '}' character in '"));
+    }
+
+    try {
+      sharedConn.nativeSQL("{call foo({unknown} )}");
+      fail("most have thrown an error");
+    } catch (SQLException e) {
+      assertTrue(e.getMessage().contains("unknown escape sequence {unknown}"));
+    }
+  }
+
+  @Test
+  public void nativeSQLNoBackSlash() throws SQLException {
+    try (Connection con = createCon()) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("SET sql_mode = concat(@@sql_mode,',NO_BACKSLASH_ESCAPES')");
+      assertEquals("call foo('{' now())", con.nativeSQL("{call foo({fn '{' now()})}"));
+    }
+  }
+
+  @Test
+  public void nativeSqlTest() throws SQLException {
+    String exp;
+    if (isMariaDBServer() || minVersion(8, 0, 17)) {
+      exp =
+          "SELECT convert(foo(a,b,c), SIGNED INTEGER)"
+              + ", convert(convert(?, CHAR), SIGNED INTEGER)"
+              + ", 1=?"
+              + ", 1=?"
+              + ", convert(?,   SIGNED INTEGER   )"
+              + ",  convert (?,   SIGNED INTEGER   )"
+              + ", convert(?, UNSIGNED INTEGER)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, DOUBLE)"
+              + ", convert(?, DOUBLE)"
+              + ", convert(?, DECIMAL)"
+              + ", convert(?, DECIMAL)"
+              + ", convert(?, DECIMAL)"
+              + ", convert(?, DATETIME)"
+              + ", convert(?, DATETIME)";
+    } else {
+      exp =
+          "SELECT convert(foo(a,b,c), SIGNED INTEGER)"
+              + ", convert(convert(?, CHAR), SIGNED INTEGER)"
+              + ", 1=?"
+              + ", 1=?"
+              + ", convert(?,   SIGNED INTEGER   )"
+              + ",  convert (?,   SIGNED INTEGER   )"
+              + ", convert(?, UNSIGNED INTEGER)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, BINARY)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", convert(?, CHAR)"
+              + ", 0.0+?"
+              + ", 0.0+?"
+              + ", convert(?, DECIMAL)"
+              + ", convert(?, DECIMAL)"
+              + ", convert(?, DECIMAL)"
+              + ", convert(?, DATETIME)"
+              + ", convert(?, DATETIME)";
+    }
+
+    assertEquals(
+        exp,
+        sharedConn.nativeSQL(
+            "SELECT {fn convert(foo(a,b,c), SQL_BIGINT)}"
+                + ", {fn convert({fn convert(?, SQL_VARCHAR)}, SQL_BIGINT)}"
+                + ", {fn convert(?, SQL_BOOLEAN )}"
+                + ", {fn convert(?, BOOLEAN)}"
+                + ", {fn convert(?,   SMALLINT   )}"
+                + ", {fn  convert (?,   TINYINT   )}"
+                + ", {fn convert(?, SQL_BIT)}"
+                + ", {fn convert(?, SQL_BLOB)}"
+                + ", {fn convert(?, SQL_VARBINARY)}"
+                + ", {fn convert(?, SQL_LONGVARBINARY)}"
+                + ", {fn convert(?, SQL_ROWID)}"
+                + ", {fn convert(?, SQL_BINARY)}"
+                + ", {fn convert(?, SQL_NCHAR)}"
+                + ", {fn convert(?, SQL_CLOB)}"
+                + ", {fn convert(?, SQL_NCLOB)}"
+                + ", {fn convert(?, SQL_DATALINK)}"
+                + ", {fn convert(?, SQL_VARCHAR)}"
+                + ", {fn convert(?, SQL_NVARCHAR)}"
+                + ", {fn convert(?, SQL_LONGVARCHAR)}"
+                + ", {fn convert(?, SQL_LONGNVARCHAR)}"
+                + ", {fn convert(?, SQL_SQLXML)}"
+                + ", {fn convert(?, SQL_LONGNCHAR)}"
+                + ", {fn convert(?, SQL_CHAR)}"
+                + ", {fn convert(?, SQL_FLOAT)}"
+                + ", {fn convert(?, SQL_DOUBLE)}"
+                + ", {fn convert(?, SQL_DECIMAL)}"
+                + ", {fn convert(?, SQL_REAL)}"
+                + ", {fn convert(?, SQL_NUMERIC)}"
+                + ", {fn convert(?, SQL_TIMESTAMP)}"
+                + ", {fn convert(?, SQL_DATETIME)}"));
+  }
+
+  @Test
+  public void doubleBackslash() throws SQLException {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    stmt.setEscapeProcessing(true);
+    stmt.execute("DROP TABLE IF EXISTS TEST_SYNTAX_ERROR");
+    stmt.execute(
+        "CREATE TABLE TEST_SYNTAX_ERROR("
+            + "     id INTEGER unsigned NOT NULL AUTO_INCREMENT, "
+            + "     str_value MEDIUMTEXT CHARACTER SET utf8mb4 NOT NULL,"
+            + "     json_value  MEDIUMTEXT CHARACTER SET utf8mb4 NOT NULL, "
+            + "    PRIMARY KEY ( id ))");
+    stmt.execute(
+        "INSERT INTO TEST_SYNTAX_ERROR(str_value, json_value) VALUES ('abc\\\\', '{\"data\":"
+            + " \"test\"}')");
+  }
+
+  @Test
+  public void databaseStateChange() throws SQLException {
+    Assumptions.assumeTrue(
+        (isMariaDBServer() && minVersion(10, 2, 0)) || (!isMariaDBServer() && minVersion(5, 7, 0)));
+    try (Connection connection = createCon()) {
+      try (Statement stmt = connection.createStatement()) {
+        stmt.execute("drop database if exists _test_db");
+        stmt.execute("create database _test_db");
+        ResultSet rs = stmt.executeQuery("SELECT DATABASE()");
+        rs.next();
+        assertEquals(rs.getString(1), connection.getCatalog());
+        stmt.execute("USE _test_db");
+        assertEquals("_test_db", connection.getCatalog());
+        stmt.execute("drop database _test_db");
+      }
+    }
+  }
+
+  @Test
+  public void catalog() throws SQLException {
+    Assumptions.assumeTrue(
+        (isMariaDBServer() && minVersion(10, 2, 0)) || (!isMariaDBServer() && minVersion(5, 7, 0)));
+    try (Connection connection = createCon()) {
+      try (Statement stmt = connection.createStatement()) {
+        stmt.execute("drop database if exists _test_db");
+        stmt.execute("create database _test_db");
+        ResultSet rs = stmt.executeQuery("SELECT DATABASE()");
+        rs.next();
+        String initialCatalog = connection.getCatalog();
+        assertEquals(rs.getString(1), initialCatalog);
+        connection.setCatalog(initialCatalog);
+        assertEquals(initialCatalog, connection.getCatalog());
+        connection.setCatalog("_test_db");
+        assertEquals("_test_db", connection.getCatalog());
+        stmt.execute("USE _test_db");
+        assertEquals("_test_db", connection.getCatalog());
+        connection.setCatalog(null);
+        assertEquals("_test_db", connection.getCatalog());
+        connection.setCatalog("_test_db");
+        assertEquals("_test_db", connection.getCatalog());
+        stmt.execute("drop database _test_db");
+        assertTrue(connection.getCatalog() == null || "_test_db".equals(connection.getCatalog()));
+      }
+    }
+  }
+
+  @Test
+  public void checkFixedData() throws SQLException {
+    sharedConn.unwrap(java.sql.Connection.class);
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> sharedConn.unwrap(String.class),
+        "The receiver is not a wrapper for java.lang.String");
+    assertTrue(sharedConn.createBlob() instanceof Blob);
+    assertTrue(sharedConn.createClob() instanceof Clob);
+    assertTrue(sharedConn.createNClob() instanceof NClob);
+    assertThrows(SQLException.class, () -> sharedConn.createSQLXML());
+    assertThrows(SQLException.class, () -> sharedConn.createArrayOf("", null));
+    assertThrows(SQLException.class, () -> sharedConn.createStruct("", null));
+    assertNull(sharedConn.getSchema());
+    sharedConn.setSchema("fff");
+    assertNull(sharedConn.getSchema());
+  }
+
+  @Test
+  public void clientInfo() throws SQLException {
+    assertTrue(sharedConn.getClientInfo().isEmpty());
+    sharedConn.setClientInfo("some", "value");
+    Properties props = new Properties();
+    props.put("another", "one");
+    props.put("and another", "two");
+    sharedConn.setClientInfo(props);
+    assertEquals(3, sharedConn.getClientInfo().size());
+    assertEquals("value", sharedConn.getClientInfo("some"));
+    assertNull(sharedConn.getClientInfo("some33"));
+  }
+
+  @Test
+  public void abortTestAlreadyClosed() throws SQLException {
+    Connection connection = createCon();
+    connection.close();
+    Executor executor = Runnable::run;
+    connection.abort(executor);
+  }
+
+  @Test
+  public void abortTestNoExecutor() {
+    try {
+      sharedConn.abort(null);
+    } catch (SQLException e) {
+      assertTrue(e.getMessage().contains("Cannot abort the connection: null executor passed"));
+    }
+  }
+
+  @Test
+  public void abortClose() throws Throwable {
+    Connection connection = createCon();
+    Statement stmt = connection.createStatement();
+    stmt.setFetchSize(1);
+    ResultSet rs =
+        stmt.executeQuery(
+            "select * from information_schema.columns as c1, "
+                + "information_schema.tables, information_schema.tables as t2");
+    assertTrue(rs.next());
+    connection.abort(Runnable::run);
+    // must still work
+
+    Thread.sleep(20);
+    try {
+      assertTrue(rs.next());
+      fail();
+    } catch (SQLException sqle) {
+      assertTrue(sqle.getMessage().contains("Operation not permit on a closed resultSet"));
+    }
+  }
+
+  @Test
+  public void verificationAbort() throws Throwable {
+    Timer timer = new Timer();
+    try (Connection connection = createCon()) {
+      timer.schedule(
+          new TimerTask() {
+            @Override
+            public void run() {
+              try {
+                connection.abort(Runnable::run);
+              } catch (SQLException sqle) {
+                fail(sqle.getMessage());
+              }
+            }
+          },
+          10);
+
+      Statement stmt = connection.createStatement();
+      assertThrows(
+          SQLException.class,
+          () ->
+              stmt.executeQuery(
+                  "select * from information_schema.columns as c1,  information_schema.tables,"
+                      + " information_schema.tables as t2"));
+    }
+  }
+
+  @Test
+  public void networkTimeoutTest() throws SQLException {
+    try (Connection connection = createCon()) {
+      assertEquals(0, connection.getNetworkTimeout());
+      int timeout = 1000;
+
+      Executor executor = Runnable::run;
+      connection.setNetworkTimeout(executor, timeout);
+      connection.isValid(2);
+      assertEquals(timeout, connection.getNetworkTimeout());
+
+      try {
+        Statement stmt = connection.createStatement();
+        stmt.execute("select sleep(2)");
+        fail("Network timeout is " + timeout / 1000 + "sec, but slept for 2 sec");
+      } catch (SQLException sqlex) {
+        assertTrue(connection.isClosed());
+      }
+    }
+  }
+
+  @Test
+  public void testConnectionAttributes() throws Exception {
+    // check if performance_schema is ON
+    Statement stmt = sharedConn.createStatement();
+    ResultSet res = stmt.executeQuery("show variables like 'performance_schema'");
+    if (res.next()) {
+      Assumptions.assumeFalse(res.getString("Value").equals("OFF"));
+
+      try (Connection connection = createCon()) {
+        Statement attributeStatement = connection.createStatement();
+        ResultSet result =
+            attributeStatement.executeQuery(
+                "select * from performance_schema.session_connect_attrs where"
+                    + " ATTR_NAME='_server_host' and processlist_id = connection_id()");
+        while (result.next()) {
+          String strVal = result.getString("ATTR_VALUE");
+          assertEquals(Configuration.parse(mDefUrl).addresses().get(0).host, strVal);
+        }
+      }
+    }
+  }
+
+  @Test
+  public void isolationLevel() throws SQLException {
+    java.sql.Connection connection = createCon();
+    int[] levels =
+        new int[] {
+          java.sql.Connection.TRANSACTION_READ_UNCOMMITTED,
+          java.sql.Connection.TRANSACTION_READ_COMMITTED,
+          java.sql.Connection.TRANSACTION_SERIALIZABLE,
+          java.sql.Connection.TRANSACTION_REPEATABLE_READ
+        };
+    for (int level : levels) {
+      connection.setTransactionIsolation(level);
+      assertEquals(level, connection.getTransactionIsolation());
+    }
+    connection.close();
+    assertThrows(
+        SQLException.class,
+        () -> connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED));
+
+    try (java.sql.Connection con2 = createCon()) {
+      try {
+        con2.setTransactionIsolation(10_000);
+        fail();
+      } catch (SQLException e) {
+        assertTrue(e.getMessage().contains("Unsupported transaction isolation level"));
+      }
+    }
+  }
+
+  @Test
+  public void savepointTest() throws SQLException {
+    try (Connection con = createCon()) {
+      Statement stmt = con.createStatement();
+      stmt.execute("CREATE TEMPORARY TABLE spt(test varchar(10))");
+      con.setAutoCommit(false);
+      stmt.executeUpdate("INSERT INTO spt values('hej1')");
+      stmt.executeUpdate("INSERT INTO spt values('hej2')");
+      Savepoint savepoint = con.setSavepoint("ye`\\\\`p");
+      stmt.executeUpdate("INSERT INTO spt  values('hej3')");
+      stmt.executeUpdate("INSERT INTO spt values('hej4')");
+      assertEquals("ye``\\\\``p", savepoint.getSavepointName());
+      Common.assertThrowsContains(
+          SQLException.class,
+          savepoint::getSavepointId,
+          "Cannot retrieve savepoint id of a named savepoint");
+      con.rollback(savepoint);
+      stmt.executeUpdate("INSERT INTO spt values('hej5')");
+      stmt.executeUpdate("INSERT INTO spt values('hej6')");
+      con.commit();
+      ResultSet rs = stmt.executeQuery("SELECT * FROM spt");
+      assertTrue(rs.next());
+      assertEquals("hej1", rs.getString(1));
+      assertTrue(rs.next());
+      assertEquals("hej2", rs.getString(1));
+      assertTrue(rs.next());
+      assertEquals("hej5", rs.getString(1));
+      assertTrue(rs.next());
+      assertEquals("hej6", rs.getString(1));
+      assertFalse(rs.next());
+    }
+  }
+
+  @Test
+  public void netWorkTimeout() throws SQLException {
+    Connection con = createCon();
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> con.setNetworkTimeout(Runnable::run, -200),
+        "Connection.setNetworkTimeout cannot be called with a negative timeout");
+    con.close();
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> con.setNetworkTimeout(Runnable::run, 200),
+        "Connection.setNetworkTimeout cannot be called on a closed connection");
+  }
+
+  @Test
+  public void savepointUnname() throws SQLException {
+    try (Connection con = createCon()) {
+      Statement stmt = con.createStatement();
+      stmt.execute("CREATE TEMPORARY TABLE spt(test varchar(10))");
+      con.setAutoCommit(false);
+      stmt.executeUpdate("INSERT INTO spt values('hej1')");
+      stmt.executeUpdate("INSERT INTO spt values('hej2')");
+      Savepoint savepoint = con.setSavepoint();
+      stmt.executeUpdate("INSERT INTO spt  values('hej3')");
+      stmt.executeUpdate("INSERT INTO spt values('hej4')");
+      assertTrue(savepoint.getSavepointId() > 0);
+      Common.assertThrowsContains(
+          SQLException.class,
+          savepoint::getSavepointName,
+          "Cannot retrieve savepoint name of an unnamed savepoint");
+      con.rollback(savepoint);
+      Common.assertThrowsContains(
+          SQLException.class, () -> con.rollback(new MySavepoint()), "Unknown savepoint type");
+      stmt.executeUpdate("INSERT INTO spt values('hej5')");
+      stmt.executeUpdate("INSERT INTO spt values('hej6')");
+      con.commit();
+      con.commit();
+      ResultSet rs = stmt.executeQuery("SELECT * FROM spt");
+      assertTrue(rs.next());
+      assertEquals("hej1", rs.getString(1));
+      assertTrue(rs.next());
+      assertEquals("hej2", rs.getString(1));
+      assertTrue(rs.next());
+      assertEquals("hej5", rs.getString(1));
+      assertTrue(rs.next());
+      assertEquals("hej6", rs.getString(1));
+      assertFalse(rs.next());
+    }
+  }
+
+  @Test
+  public void releaseSavepoint() throws SQLException {
+    try (Connection con = createCon()) {
+      Statement stmt = con.createStatement();
+      stmt.execute("CREATE TEMPORARY TABLE spt(test varchar(10)) ");
+      con.setAutoCommit(false);
+      stmt.executeUpdate("INSERT INTO spt values('hej1')");
+      stmt.executeUpdate("INSERT INTO spt values('hej2')");
+      Savepoint savepoint = con.setSavepoint();
+      stmt.executeUpdate("INSERT INTO spt  values('hej3')");
+      stmt.executeUpdate("INSERT INTO spt values('hej4')");
+      con.releaseSavepoint(savepoint);
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> con.releaseSavepoint(new MySavepoint()),
+          "Unknown savepoint type");
+      stmt.executeUpdate("INSERT INTO spt values('hej5')");
+      stmt.executeUpdate("INSERT INTO spt values('hej6')");
+      con.commit();
+      ResultSet rs = stmt.executeQuery("SELECT * FROM spt");
+      for (int i = 1; i < 7; i++) {
+        assertTrue(rs.next());
+        assertEquals("hej" + i, rs.getString(1));
+      }
+      assertFalse(rs.next());
+    }
+  }
+
+  static class MySavepoint implements Savepoint {
+    @Override
+    public int getSavepointId() throws SQLException {
+      return 0;
+    }
+
+    @Override
+    public String getSavepointName() throws SQLException {
+      return null;
+    }
+  }
+
+  @Nested
+  @DisplayName("Transaction Test")
+  class Transaction {
+
+    @Test
+    public void testProperRollback() throws Exception {
+      java.sql.Statement stmt = sharedConn.createStatement();
+      try {
+        stmt.execute("CREATE TABLE tx_prim_key(id int not null primary key) engine=innodb");
+        stmt.execute(
+            "CREATE TABLE tx_fore_key (id int not null primary key, id_ref int not null, foreign"
+                + " key (id_ref) references tx_prim_key(id) on delete restrict on update restrict) "
+                + "engine=innodb");
+        stmt.executeUpdate("insert into tx_prim_key(id) values(32)");
+        stmt.executeUpdate("insert into tx_fore_key(id, id_ref) values(42, 32)");
+
+        // 2. try to delete entry in Primary table in a transaction - which will fail due
+        // foreign key.
+        sharedConn.setAutoCommit(false);
+        try (java.sql.Statement st = sharedConn.createStatement()) {
+          st.executeUpdate("delete from tx_prim_key where id = 32");
+          sharedConn.commit();
+          fail("Expected SQLException");
+        } catch (SQLException e) {
+          // This exception is expected
+          assertTrue(
+              e.getMessage().contains("a foreign key constraint fails")
+                  || e.getMessage().contains("Foreign key constraint violation"));
+          sharedConn.rollback();
+        }
+
+        try (java.sql.Connection conn2 = createCon();
+            java.sql.Statement st = conn2.createStatement()) {
+          st.setQueryTimeout(30000);
+          st.executeUpdate("delete from tx_fore_key where id = 42");
+          st.executeUpdate("delete from tx_prim_key where id = 32");
+        }
+
+      } finally {
+        stmt.execute("drop table if exists tx_fore_key");
+        stmt.execute("drop table if exists tx_prim_key");
+      }
+    }
+
+    @Test
+    public void transactionTest() throws SQLException {
+      Statement stmt = sharedConn.createStatement();
+      try {
+        stmt.execute(
+            "CREATE TABLE transaction_test "
+                + "(id int not null primary key auto_increment, test varchar(20)) "
+                + "engine=innodb");
+        sharedConn.setAutoCommit(false);
+        stmt.executeUpdate("INSERT INTO transaction_test (test) VALUES ('heja')");
+        stmt.executeUpdate("INSERT INTO transaction_test (test) VALUES ('japp')");
+        sharedConn.commit();
+        ResultSet rs = stmt.executeQuery("SELECT * FROM transaction_test");
+        assertEquals(true, rs.next());
+        assertEquals("heja", rs.getString("test"));
+        assertEquals(true, rs.next());
+        assertEquals("japp", rs.getString("test"));
+        assertEquals(false, rs.next());
+        stmt.executeUpdate(
+            "INSERT INTO transaction_test (test) VALUES ('rollmeback')",
+            java.sql.Statement.RETURN_GENERATED_KEYS);
+        ResultSet rsGen = stmt.getGeneratedKeys();
+        rsGen.next();
+        int[] autoInc = setAutoInc();
+        assertEquals(autoInc[1] + autoInc[0] * 3, rsGen.getInt(1));
+        sharedConn.rollback();
+        rs = stmt.executeQuery("SELECT * FROM transaction_test WHERE id=3");
+        assertEquals(false, rs.next());
+        sharedConn.setAutoCommit(true);
+      } finally {
+        stmt.execute("DROP TABLE IF EXISTS transaction_test");
+      }
+    }
+
+    /**
+     * Get current autoincrement value, since Galera values are automatically set.
+     *
+     * @throws SQLException if any error occur.
+     */
+    public int[] setAutoInc() throws SQLException {
+      return setAutoInc(1, 0);
+    }
+
+    /**
+     * Get current autoincrement value, since Galera values are automatically set.
+     *
+     * @param autoIncInit default increment
+     * @param autoIncOffsetInit default increment offset
+     * @throws SQLException if any error occur
+     * @see <a
+     *     href="https://mariadb.org/auto-increments-in-galera/">https://mariadb.org/auto-increments-in-galera/</a>
+     */
+    public int[] setAutoInc(int autoIncInit, int autoIncOffsetInit) throws SQLException {
+
+      // in case of galera
+      //      if (isGalera()) {
+      //        ResultSet rs =
+      //            sharedConn.createStatement().executeQuery("show variables like
+      // '%auto_increment%'");
+      //        while (rs.next()) {
+      //          if ("auto_increment_increment".equals(rs.getString(1))) {
+      //            autoInc = rs.getInt(2);
+      //          }
+      //          if ("auto_increment_offset".equals(rs.getString(1))) {
+      //            autoIncOffset = rs.getInt(2);
+      //          }
+      //        }
+      //        if (autoInc == 1) {
+      //          // galera with one node only, then offset is not used
+      //          autoIncOffset = 0;
+      //        }
+      //      }
+      return new int[] {autoIncInit, autoIncOffsetInit};
+    }
+  }
+
+  @Test
+  public void various() throws SQLException {
+    assertThrows(SQLException.class, () -> sharedConn.setTypeMap(null));
+    assertTrue(sharedConn.getTypeMap().isEmpty());
+    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, sharedConn.getHoldability());
+    sharedConn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
+    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, sharedConn.getHoldability());
+  }
+
+  @Test
+  public void verificationEd25519AuthPlugin() throws Throwable {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && isMariaDBServer()
+            && minVersion(10, 2, 0));
+    Statement stmt = sharedConn.createStatement();
+
+    try {
+      stmt.execute("INSTALL SONAME 'auth_ed25519'");
+    } catch (SQLException sqle) {
+      Assumptions.assumeTrue(false, "server doesn't have ed25519 plugin, cancelling test");
+    }
+    try {
+      stmt.execute("drop user verificationEd25519AuthPlugin@'%'");
+    } catch (SQLException e) {
+      // eat
+    }
+    try {
+      if (minVersion(10, 4, 0)) {
+        stmt.execute(
+            "CREATE USER IF NOT EXISTS verificationEd25519AuthPlugin@'%' IDENTIFIED "
+                + "VIA ed25519 USING PASSWORD('MySup8%rPassw@ord')");
+      } else {
+        stmt.execute(
+            "CREATE USER IF NOT EXISTS verificationEd25519AuthPlugin@'%' IDENTIFIED "
+                + "VIA ed25519 USING '6aW9C7ENlasUfymtfMvMZZtnkCVlcb1ssxOLJ0kj/AA'");
+      }
+    } catch (SQLException sqle) {
+      // already existing
+    }
+    stmt.execute(
+        "GRANT SELECT on " + sharedConn.getCatalog() + ".* to verificationEd25519AuthPlugin");
+
+    try (Connection connection =
+        createCon("user=verificationEd25519AuthPlugin&password=MySup8%rPassw@ord")) {
+      // must have succeeded
+      connection.getCatalog();
+    }
+    stmt.execute("drop user verificationEd25519AuthPlugin@'%'");
+  }
+
+  @Test
+  public void pamAuthPlugin() throws Throwable {
+    // https://mariadb.com/kb/en/authentication-plugin-pam/
+    // only test on travis, because only work on Unix-like operating systems.
+    // /etc/pam.d/mariadb pam configuration is created beforehand
+
+    Assumptions.assumeTrue(
+        isMariaDBServer()
+            && System.getenv("TEST_PAM_USER") != null
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("INSTALL PLUGIN pam SONAME 'auth_pam'");
+    } catch (SQLException sqle) {
+      // might be already set
+    }
+
+    String pamUser = System.getenv("TEST_PAM_USER");
+    String pamPwd = System.getenv("TEST_PAM_PWD");
+    try {
+      stmt.execute("DROP USER '" + pamUser + "'@'%'");
+    } catch (SQLException e) {
+      // eat
+    }
+    stmt.execute("CREATE USER '" + pamUser + "'@'%' IDENTIFIED VIA pam USING 'mariadb'");
+    stmt.execute("GRANT SELECT ON *.* TO '" + pamUser + "'@'%' IDENTIFIED VIA pam");
+
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES");
+
+    int testPort = port;
+    if (System.getenv("TEST_PAM_PORT") != null) {
+      testPort = Integer.parseInt(System.getenv("TEST_PAM_PORT"));
+    }
+    String connStr =
+        String.format(
+            "jdbc:mariadb://%s:%s/%s?user=%s&password=%s&%s",
+            hostname, testPort, database, pamUser, pamPwd, defaultOther);
+    try {
+      try (Connection connection =
+          DriverManager.getConnection(connStr + "&restrictedAuth=dialog")) {
+        // must have succeeded
+        connection.getCatalog();
+      }
+    } catch (SQLException e) {
+      System.err.println("fail with connectionString : " + connStr + "&restrictedAuth=dialog");
+      throw e;
+    }
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> DriverManager.getConnection(connStr + "&restrictedAuth=other"),
+        "Client restrict authentication plugin to a limited set of authentication");
+
+    stmt.execute("drop user " + pamUser + "@'%'");
+  }
+
+  @Nested
+  @DisplayName("Compression Test")
+  class Compression {
+
+    @Test
+    public void testConnection() throws Exception {
+      try (Connection connection = createCon("useCompression")) {
+        // must have succeeded
+        connection.getCatalog();
+      }
+    }
+  }
+
+  @Test
+  public void testNoUseReadAheadInputConnection() throws Exception {
+    try (Connection connection = createCon("useReadAheadInput=false")) {
+      // must have succeeded
+      Statement stmt = connection.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10");
+      int i = 0;
+      while (rs.next()) i++;
+      assertTrue(i > 0);
+    }
+  }
+
+  @Test
+  public void useNoDatabase() throws SQLException {
+    try (Connection con = createCon()) {
+      con.getCatalog();
+      Statement stmt = con.createStatement();
+      stmt.execute("CREATE DATABASE IF NOT EXISTS someDb");
+      con.setCatalog("someDb");
+      stmt.execute("DROP DATABASE someDb");
+      if (minVersion(10, 4, 0)
+          && !"maxscale".equals(System.getenv("srv"))
+          && !"skysql-ha".equals(System.getenv("srv"))) {
+        assertNull(con.getCatalog());
+      }
+    }
+  }
+
+  @Test
+  public void windowsNamedPipe() throws SQLException {
+    Assumptions.assumeTrue(isMariaDBServer() || !minVersion(8, 0, 14));
+    ResultSet rs = null;
+    try {
+      rs = sharedConn.createStatement().executeQuery("select @@named_pipe,@@socket");
+    } catch (SQLException sqle) {
+      // on non Windows system, named_pipe doesn't exist.
+    }
+    if (rs != null) {
+      assertTrue(rs.next());
+      System.out.println("named_pipe:" + rs.getString(1));
+      Assumptions.assumeTrue(rs.getBoolean(1));
+      String namedPipeName = rs.getString(2);
+      System.out.println("namedPipeName:" + namedPipeName);
+
+      // skip test if no namedPipeName was obtained because then we do not use a socket connection
+      Assumptions.assumeTrue(namedPipeName != null);
+      try (Connection connection = createCon("pipe=" + namedPipeName)) {
+        java.sql.Statement stmt = connection.createStatement();
+        try (ResultSet rs2 = stmt.executeQuery("SELECT 1")) {
+          assertTrue(rs2.next());
+        }
+      }
+      // connection without host name
+      try (java.sql.Connection connection =
+          DriverManager.getConnection(
+              String.format(
+                  "jdbc:mariadb:///%s?%s&pipe=%s&tcpAbortiveClose&tcpKeepAlive",
+                  sharedConn.getCatalog(),
+                  mDefUrl.substring(mDefUrl.indexOf("?user=") + 1),
+                  namedPipeName))) {
+        connection.setNetworkTimeout(null, 300);
+        java.sql.Statement stmt = connection.createStatement();
+        try (ResultSet rs2 = stmt.executeQuery("SELECT 1")) {
+          assertTrue(rs2.next());
+        }
+      }
+    }
+  }
+
+  @Test
+  public void localSocket() throws Exception {
+    Assumptions.assumeTrue(
+        System.getenv("local") != null
+            && "1".equals(System.getenv("local"))
+            && !System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win"));
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("select @@version_compile_os,@@socket");
+    if (!rs.next() || rs.getString(2) == null) {
+      return;
+    }
+    String path = rs.getString(2);
+    try {
+      stmt.execute("DROP USER testSocket");
+    } catch (SQLException e) {
+      // eat
+    }
+    boolean useOldNotation =
+        (!isMariaDBServer() || !minVersion(10, 2, 0))
+            && (isMariaDBServer() || !minVersion(8, 0, 0));
+    if (useOldNotation) {
+      stmt.execute("CREATE USER testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
+      stmt.execute("GRANT SELECT on *.* to testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
+    } else {
+      stmt.execute("CREATE USER testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
+      stmt.execute("GRANT SELECT on *.* to testSocket");
+    }
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES");
+
+    String url =
+        String.format(
+            "jdbc:mariadb:///%s?user=testSocket&password=heyPassw!µ20§rd&localSocket=%s&tcpAbortiveClose&tcpKeepAlive",
+            sharedConn.getCatalog(), path);
+
+    try (java.sql.Connection connection = DriverManager.getConnection(url)) {
+      connection.setNetworkTimeout(null, 300);
+      rs = connection.createStatement().executeQuery("select 1");
+      assertTrue(rs.next());
+    }
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () ->
+            DriverManager.getConnection(
+                "jdbc:mariadb:///"
+                    + sharedConn.getCatalog()
+                    + "?user=testSocket&password=heyPassw!µ20§rd&localSocket=/wrongPath"),
+        "Socket fail to connect to host");
+
+    if (haveSsl()) {
+      String serverCertPath = SslTest.retrieveCertificatePath();
+      if (serverCertPath != null) {
+        try (Connection con =
+            DriverManager.getConnection(
+                "jdbc:mariadb:///"
+                    + sharedConn.getCatalog()
+                    + "?sslMode=verify-full&user=testSocket&password=heyPassw!µ20§rd"
+                    + "&serverSslCert="
+                    + serverCertPath
+                    + "&localSocket="
+                    + path)) {
+          rs = con.createStatement().executeQuery("select 1");
+          assertTrue(rs.next());
+        }
+      }
+    }
+    stmt.execute("DROP USER testSocket");
+  }
+
+  @Test
+  public void socketFactoryTest() throws SQLException {
+    try (Connection conn = createCon("socketFactory=" + SocketFactoryBasicTest.class.getName())) {
+      conn.isValid(1);
+    }
+
+    try (Connection conn = createCon("socketFactory=" + SocketFactoryTest.class.getName())) {
+      conn.isValid(1);
+    }
+
+    Common.assertThrowsContains(
+        SQLNonTransientConnectionException.class,
+        () -> createCon("socketFactory=wrongClass"),
+        "Socket factory failed to initialized with option \"socketFactory\" set to \"wrongClass\"");
+  }
+
+  @Test
+  public void socketOption() throws SQLException {
+    try (Connection con = createCon("tcpKeepAlive=true&tcpAbortiveClose=true")) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void sslNotSet() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    Assumptions.assumeFalse(haveSsl());
+    Common.assertThrowsContains(
+        SQLException.class, () -> createCon("sslMode=trust"), "ssl not enabled in the server");
+  }
+
+  @Test
+  public void localSocketAddress() throws SQLException {
+    Assumptions.assumeTrue(
+        System.getenv("local") != null
+            && "1".equals(System.getenv("local"))
+            && !System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win"));
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try (Connection con = createCon("localSocketAddress=" + hostAddress.host)) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void setReadOnly() throws SQLException {
+    Connection con = createCon();
+    con.setReadOnly(true);
+    con.close();
+    Common.assertThrowsContains(
+        SQLNonTransientConnectionException.class,
+        () -> con.setReadOnly(false),
+        "Connection is closed");
+  }
+
+  @Test
+  public void timezone() throws SQLException {
+    try (Connection con = createCon("timezone=GMT-8")) {
+      Statement statement = con.createStatement();
+      ResultSet rs = statement.executeQuery("SELECT @@time_zone");
+      rs.next();
+      assertEquals("-08:00", rs.getString(1));
+    }
+
+    try (Connection con = createCon("timezone=UTC")) {
+      Statement statement = con.createStatement();
+      ResultSet rs = statement.executeQuery("SELECT @@time_zone, @@system_time_zone");
+      rs.next();
+      String srvTz = rs.getString(1);
+      if ("SYSTEM".equals(rs.getString(1))) {
+        srvTz = rs.getString(2);
+      }
+      assertTrue("+00:00".equals(srvTz) || "UTC".equals(srvTz));
+    }
+
+    try (Connection con = createCon("timezone=disable")) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void createDatabaseIfNotExist() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    // ensure connecting without DB
+    String connStr =
+        String.format(
+            "jdbc:mariadb://%s:%s/?user=%s&password=%s&%s&createDatabaseIfNotExist",
+            hostname, port, user, password, defaultOther);
+    try (Connection con = DriverManager.getConnection(connStr)) {
+      con.createStatement().executeQuery("SELECT 1");
+    }
+    sharedConn.createStatement().execute("DROP DATABASE IF EXISTS `bla``f``l`");
+    String nonExistentDatabase = "bla`f`l";
+    connStr =
+        String.format(
+            "jdbc:mariadb://%s:%s/%s?user=%s&password=%s&%s&createDatabaseIfNotExist",
+            hostname, port, nonExistentDatabase, user, password, defaultOther);
+    try (Connection con = DriverManager.getConnection(connStr)) {
+      ResultSet rs = con.createStatement().executeQuery("select DATABASE()");
+      assertTrue(rs.next());
+      assertEquals(nonExistentDatabase, rs.getString(1));
+    }
+
+    nonExistentDatabase = "bla`f`l0";
+    connStr =
+        String.format(
+            "jdbc:mariadb:replication://%s:%s,%s:%s/%s?user=%s&password=%s&%s&createDatabaseIfNotExist",
+            hostname, port, hostname, port, nonExistentDatabase, user, password, defaultOther);
+    try (Connection con = DriverManager.getConnection(connStr)) {
+      ResultSet rs = con.createStatement().executeQuery("select DATABASE()");
+      assertTrue(rs.next());
+      assertEquals(nonExistentDatabase, rs.getString(1));
+    }
+
+    sharedConn.createStatement().execute("DROP DATABASE IF EXISTS `bla``f``l`");
+    sharedConn.createStatement().execute("DROP DATABASE IF EXISTS `bla``f``l0`");
+  }
+
+  @Test
+  public void loopHost() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    // ensure connecting without DB
+    String connStr =
+        String.format(
+            "jdbc:mariadb://wronghost,%s:%s/%s?user=%s&password=%s&%s",
+            hostname, port, database, user, password, defaultOther);
+    try (Connection con = DriverManager.getConnection(connStr)) {
+      con.createStatement().executeQuery("SELECT 1");
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/CredentialPluginTest.java b/src/test/java/org/mariadb/jdbc/integration/CredentialPluginTest.java
new file mode 100644
index 0000000..fbf197c
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/CredentialPluginTest.java
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.SetEnvironmentVariable;
+
+public class CredentialPluginTest extends Common {
+
+  /**
+   * Create temporary test User.
+   *
+   * @throws SQLException if any
+   */
+  @BeforeAll
+  public static void beforeTest() throws SQLException {
+    String version = System.getProperty("java.version");
+    int majorVersion = Integer.parseInt(version.substring(0, version.indexOf(".")));
+    Assumptions.assumeTrue(majorVersion < 17);
+
+    Assumptions.assumeTrue(isMariaDBServer());
+    drop();
+    boolean useOldNotation =
+        (!isMariaDBServer() || !minVersion(10, 2, 0))
+            && (isMariaDBServer() || !minVersion(8, 0, 0));
+    Statement stmt = sharedConn.createStatement();
+    if (useOldNotation) {
+      stmt.execute("CREATE USER 'identityUser'@'localhost'");
+      stmt.execute(
+          "GRANT SELECT ON "
+              + sharedConn.getCatalog()
+              + ".* TO 'identityUser'@'localhost' IDENTIFIED BY '!Passw0rd3Works'");
+      stmt.execute("CREATE USER 'identityUser'@'%'");
+      stmt.execute(
+          "GRANT SELECT ON "
+              + sharedConn.getCatalog()
+              + ".* TO 'identityUser'@'%' IDENTIFIED BY '!Passw0rd3Works'");
+    } else {
+      stmt.execute("CREATE USER 'identityUser'@'localhost' IDENTIFIED BY '!Passw0rd3Works'");
+      stmt.execute(
+          "GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO 'identityUser'@'localhost'");
+      stmt.execute("CREATE USER 'identityUser'@'%' IDENTIFIED BY '!Passw0rd3Works'");
+      stmt.execute("GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO 'identityUser'@'%'");
+    }
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES");
+  }
+
+  /**
+   * remove temporary test User.
+   *
+   * @throws SQLException if any
+   */
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("DROP USER 'identityUser'@'%'");
+    } catch (SQLException e) {
+      // eat
+    }
+    try {
+      stmt.execute("DROP USER 'identityUser'@'localhost'");
+    } catch (SQLException e) {
+      // eat
+    }
+  }
+
+  @Test
+  public void propertiesIdentityTest() throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> createCon("credentialType=PROPERTY&user=identityUser"),
+        "Access denied");
+
+    System.setProperty("mariadb.user", "identityUser");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> createCon("credentialType=PROPERTY&pwdKey=myPwdKey"),
+        "Access denied");
+
+    System.setProperty("myPwdKey", "!Passw0rd3Works");
+    try (Connection conn = createCon("credentialType=PROPERTY&pwdKey=myPwdKey")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+
+    System.setProperty("mariadb.pwd", "!Passw0rd3Works");
+
+    try (Connection conn = createCon("credentialType=PROPERTY")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+  }
+
+  @Test
+  public void specificPropertiesIdentityTest() throws SQLException {
+
+    System.setProperty("myUserKey", "identityUser");
+    System.setProperty("myPwdKey", "!Passw0rd3Works");
+
+    try (Connection conn = createCon("credentialType=PROPERTY&userKey=myUserKey&pwdKey=myPwdKey")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+  }
+
+  @Test
+  public void unknownCredentialTest() {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> createCon("credentialType=UNKNOWN"),
+        "No identity plugin registered with the type \"UNKNOWN\"");
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void noEnvsIdentityTest() throws Exception {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> createCon("&user=toti&credentialType=ENV&pwdKey=myPwdKey"),
+        "Access denied");
+  }
+
+  @Test
+  @SetEnvironmentVariable(key = "myPwdKey", value = "!Passw0rd3Works")
+  public void envsPwdTest() throws Exception {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> createCon("&user=toto&credentialType=ENV&pwdKey=myPwdKey"),
+        "Access denied");
+
+    try (Connection conn = createCon("user=identityUser&credentialType=ENV&pwdKey=myPwdKey")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+  }
+
+  @Test
+  @SetEnvironmentVariable(key = "myPwdKey", value = "!Passw0rd3Works")
+  @SetEnvironmentVariable(key = "MARIADB_USER", value = "identityUser")
+  public void envsDefaultIdentityAndPwdTest() throws Exception {
+    try (Connection conn = createCon("credentialType=ENV&pwdKey=myPwdKey")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+  }
+
+  @Test
+  @SetEnvironmentVariable(key = "MARIADB_PWD", value = "!Passw0rd3Works")
+  @SetEnvironmentVariable(key = "MARIADB_USER", value = "identityUser")
+  public void envsIdentityDefaultPwdTest() throws Exception {
+
+    try (Connection conn = createCon("credentialType=ENV")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+  }
+
+  @Test
+  @SetEnvironmentVariable(key = "myPwdKey", value = "!Passw0rd3Works")
+  @SetEnvironmentVariable(key = "myUserKey", value = "identityUser")
+  public void envsIdentityAndPwdTest() throws Exception {
+
+    try (Connection conn = createCon("credentialType=ENV&userKey=myUserKey&pwdKey=myPwdKey")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+  }
+
+  @Test
+  // @ClearSystemProperty(key = "some key")
+  @SetEnvironmentVariable(key = "MARIADB2_USER", value = "identityUser")
+  @SetEnvironmentVariable(key = "MARIADB2_PWD", value = "!Passw0rd3Works")
+  @SuppressWarnings("unchecked")
+  public void envTestsIdentityTest() throws Exception {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+    Assumptions.assumeTrue(isMariaDBServer() && haveSsl());
+
+    assertThrows(SQLException.class, () -> createCon("credentialType=ENVTEST&sslMode=DISABLE"));
+    assertThrows(SQLException.class, () -> createCon("credentialType=ENVTEST"));
+
+    try (Connection conn = createCon("credentialType=ENVTEST&sslMode=TRUST")) {
+      Statement stmt = conn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT '5'");
+      assertTrue(rs.next());
+      assertEquals("5", rs.getString(1));
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/DataSourceTest.java b/src/test/java/org/mariadb/jdbc/integration/DataSourceTest.java
new file mode 100644
index 0000000..b591d86
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/DataSourceTest.java
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import javax.sql.DataSource;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbDataSource;
+
+public class DataSourceTest extends Common {
+
+  @Test
+  public void basic() throws SQLException {
+    MariaDbDataSource ds = new MariaDbDataSource(mDefUrl);
+    testDs(ds);
+
+    ds = new MariaDbDataSource();
+    ds.setUrl(mDefUrl);
+    testDs(ds);
+
+    ds = new MariaDbDataSource();
+    ds.setPassword("ttt");
+    ds.setUrl(mDefUrl);
+    assertThrows(SQLException.class, ds::getConnection);
+  }
+
+  private void testDs(MariaDbDataSource ds) throws SQLException {
+    try (Connection con1 = ds.getConnection()) {
+      try (Connection con2 = ds.getConnection()) {
+
+        ResultSet rs1 = con1.createStatement().executeQuery("SELECT 1");
+        ResultSet rs2 = con2.createStatement().executeQuery("SELECT 2");
+        while (rs1.next()) {
+          assertEquals(1, rs1.getInt(1));
+        }
+        while (rs2.next()) {
+          assertEquals(2, rs2.getInt(1));
+        }
+      }
+    }
+
+    PooledConnection con1 = null;
+    PooledConnection con2 = null;
+    try {
+      con1 = ds.getPooledConnection();
+      con2 = ds.getPooledConnection();
+
+      ResultSet rs1 = con1.getConnection().createStatement().executeQuery("SELECT 1");
+      ResultSet rs2 = con2.getConnection().createStatement().executeQuery("SELECT 2");
+      while (rs1.next()) {
+        assertEquals(1, rs1.getInt(1));
+      }
+      while (rs2.next()) {
+        assertEquals(2, rs2.getInt(1));
+      }
+
+    } finally {
+      if (con1 != null) con1.close();
+      if (con2 != null) con2.close();
+    }
+
+    XAConnection conx1 = null;
+    XAConnection conx2 = null;
+    try {
+      conx1 = ds.getXAConnection();
+      conx2 = ds.getXAConnection();
+
+      ResultSet rs1 = conx1.getConnection().createStatement().executeQuery("SELECT 1");
+      ResultSet rs2 = conx2.getConnection().createStatement().executeQuery("SELECT 2");
+      while (rs1.next()) {
+        assertEquals(1, rs1.getInt(1));
+      }
+      while (rs2.next()) {
+        assertEquals(2, rs2.getInt(1));
+      }
+
+    } finally {
+      if (conx1 != null) con1.close();
+      if (conx2 != null) con2.close();
+    }
+  }
+
+  @Test
+  public void basic2() throws SQLException {
+    MariaDbDataSource ds = new MariaDbDataSource();
+    assertNull(ds.getUrl());
+    assertNull(ds.getUser());
+    assertEquals(30, ds.getLoginTimeout());
+    DriverManager.setLoginTimeout(40);
+    assertEquals(40, ds.getLoginTimeout());
+    DriverManager.setLoginTimeout(0);
+    ds.setLoginTimeout(50);
+    assertEquals(50, ds.getLoginTimeout());
+
+    assertThrows(SQLException.class, () -> ds.getConnection());
+    assertThrows(SQLException.class, () -> ds.getConnection("user", "password"));
+    assertThrows(SQLException.class, () -> ds.getPooledConnection());
+    assertThrows(SQLException.class, () -> ds.getPooledConnection("user", "password"));
+    assertThrows(SQLException.class, () -> ds.getXAConnection());
+    assertThrows(SQLException.class, () -> ds.getXAConnection("user", "password"));
+
+    ds.setUser("dd");
+    assertEquals("dd", ds.getUser());
+
+    ds.setPassword("pwd");
+    assertThrows(SQLException.class, () -> ds.getConnection());
+    assertThrows(SQLException.class, () -> ds.getPooledConnection());
+
+    assertThrows(SQLException.class, () -> ds.setUrl("jdbc:wrong://d"));
+
+    ds.setUrl("jdbc:mariadb://myhost:5500/db?someOption=val");
+    assertEquals(
+        "jdbc:mariadb://myhost:5500/db?user=dd&password=***&someOption=val&connectTimeout=50000",
+        ds.getUrl());
+  }
+
+  @Test
+  public void switchUser() throws SQLException {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("DROP USER 'dsUser'");
+    } catch (SQLException e) {
+      // eat
+    }
+
+    if (minVersion(8, 0, 0)) {
+      if (isMariaDBServer()) {
+        stmt.execute("CREATE USER 'dsUser'@'%' IDENTIFIED BY 'MySup8%rPassw@ord'");
+        stmt.execute("GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO 'dsUser'@'%'");
+      } else {
+        stmt.execute(
+            "CREATE USER 'dsUser'@'%' IDENTIFIED WITH mysql_native_password BY"
+                + " 'MySup8%rPassw@ord'");
+        stmt.execute("GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO 'dsUser'@'%'");
+      }
+    } else {
+      stmt.execute("CREATE USER 'dsUser'@'%'");
+      stmt.execute(
+          "GRANT SELECT ON "
+              + sharedConn.getCatalog()
+              + ".* TO 'dsUser'@'%' IDENTIFIED BY 'MySup8%rPassw@ord'");
+    }
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES");
+
+    DataSource ds = new MariaDbDataSource(mDefUrl + "&allowPublicKeyRetrieval");
+    try (Connection con1 = ds.getConnection()) {
+      try (Connection con2 = ds.getConnection("dsUser", "MySup8%rPassw@ord")) {
+        ResultSet rs1 = con1.createStatement().executeQuery("SELECT 1");
+        ResultSet rs2 = con2.createStatement().executeQuery("SELECT 2");
+        while (rs1.next()) {
+          assertEquals(1, rs1.getInt(1));
+        }
+        while (rs2.next()) {
+          assertEquals(2, rs2.getInt(1));
+        }
+      }
+    } finally {
+      try {
+        stmt.execute("DROP USER 'dsUser'");
+      } catch (SQLException e) {
+        // eat
+      }
+    }
+
+    // mysql has issue when creating new user with native password
+    if (haveSsl() && !isMariaDBServer() && minVersion(8, 0, 0)) {
+      try (Connection con = createCon("sslMode=trust")) {
+        con.createStatement().execute("DO 1");
+      }
+    }
+  }
+
+  @Test
+  public void exceptions() throws SQLException {
+    DataSource ds = new MariaDbDataSource(mDefUrl);
+    ds.unwrap(javax.sql.DataSource.class);
+    ds.unwrap(MariaDbDataSource.class);
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> ds.unwrap(String.class),
+        "Datasource is not a wrapper for java.lang.String");
+
+    assertTrue(ds.isWrapperFor(javax.sql.DataSource.class));
+    assertTrue(ds.isWrapperFor(MariaDbDataSource.class));
+    assertFalse(ds.isWrapperFor(String.class));
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> new MariaDbDataSource("jdbc:wrongUrl"),
+        "Wrong mariaDB url: jdbc:wrongUrl");
+    assertNull(ds.getLogWriter());
+    assertNull(ds.getParentLogger());
+    ds.setLogWriter(null);
+
+    assertEquals(30, ds.getLoginTimeout());
+    ds.setLoginTimeout(60);
+    assertEquals(60, ds.getLoginTimeout());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/DatabaseMetadataTest.java b/src/test/java/org/mariadb/jdbc/integration/DatabaseMetadataTest.java
new file mode 100644
index 0000000..6ca03cb
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/DatabaseMetadataTest.java
@@ -0,0 +1,2176 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.Statement;
+
+public class DatabaseMetadataTest extends Common {
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS getProcTimePrecision");
+    stmt.execute("DROP PROCEDURE IF EXISTS getProcTimePrecision2");
+    stmt.execute("DROP PROCEDURE IF EXISTS testMetaCatalog");
+    stmt.execute("DROP TABLE IF EXISTS json_test");
+    stmt.execute("DROP TABLE IF EXISTS dbpk_test");
+    stmt.execute("DROP TABLE IF EXISTS datetime_test");
+    stmt.execute("DROP TABLE IF EXISTS manycols");
+    stmt.execute("DROP TABLE IF EXISTS ytab");
+    stmt.execute("DROP TABLE IF EXISTS maxcharlength");
+    stmt.execute("DROP TABLE IF EXISTS conj72");
+    stmt.execute("DROP TABLE IF EXISTS getTimePrecision");
+    stmt.execute("DROP TABLE IF EXISTS getPrecision");
+    stmt.execute("DROP TABLE IF EXISTS versionTable");
+    stmt.execute("DROP TABLE IF EXISTS tablegetcolumns");
+    stmt.execute("drop table if exists getBestRowIdentifier1");
+    stmt.execute("drop table if exists getBestRowIdentifier2");
+    stmt.execute("drop table if exists cross3");
+    stmt.execute("drop table if exists cross2");
+    stmt.execute("drop table if exists cross1");
+    stmt.execute("drop table if exists get_index_info");
+    stmt.execute("drop table if exists text_types_text");
+  }
+
+  @BeforeAll
+  public static void initClass() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE IF NOT EXISTS getTimePrecision("
+            + "d date, "
+            + "t1 datetime(0),"
+            + "t2 datetime(6),"
+            + "t3 timestamp(0) DEFAULT '2000-01-01 00:00:00',"
+            + "t4 timestamp(6) DEFAULT '2000-01-01 00:00:00',"
+            + "t5 time(0),"
+            + "t6 time(6))");
+    stmt.execute("CREATE TABLE json_test(t1 JSON)");
+    stmt.execute(
+        "CREATE PROCEDURE testMetaCatalog(x int, out y int) COMMENT 'comments' \n"
+            + "BEGIN\n"
+            + "SELECT 1;end\n");
+    stmt.execute(
+        "CREATE TABLE IF NOT EXISTS dbpk_test(val varchar(20), id1 int not null, id2 int not"
+            + " null,primary key(id1, id2)) engine=innodb");
+    stmt.execute("CREATE TABLE IF NOT EXISTS datetime_test(dt datetime)");
+    stmt.execute(
+        "CREATE TABLE IF NOT EXISTS `manycols`(  `tiny` tinyint(4) DEFAULT NULL,  `tiny_uns`"
+            + " tinyint(3) unsigned DEFAULT NULL,  `small` smallint(6) DEFAULT NULL,  `small_uns`"
+            + " smallint(5) unsigned DEFAULT NULL,  `medium` mediumint(9) DEFAULT NULL, "
+            + " `medium_uns` mediumint(8) unsigned DEFAULT NULL,  `int_col` int(11) DEFAULT NULL, "
+            + " `int_col_uns` int(10) unsigned DEFAULT NULL,  `big` bigint(20) DEFAULT NULL, "
+            + " `big_uns` bigint(20) unsigned DEFAULT NULL,  `decimal_col` decimal(10,5) DEFAULT"
+            + " NULL,  `fcol` float DEFAULT NULL,  `fcol_uns` float unsigned DEFAULT NULL,  `dcol`"
+            + " double DEFAULT NULL,  `dcol_uns` double unsigned DEFAULT NULL,  `date_col` date"
+            + " DEFAULT NULL,  `time_col` time DEFAULT NULL,  `timestamp_col` timestamp NOT NULL"
+            + " DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  `year_col` year(4) DEFAULT"
+            + " NULL,  `bit_col` bit(5) DEFAULT NULL,  `char_col` char(5) DEFAULT NULL, "
+            + " `varchar_col` varchar(10) DEFAULT NULL,  `binary_col` binary(10) DEFAULT NULL, "
+            + " `varbinary_col` varbinary(10) DEFAULT NULL,  `tinyblob_col` tinyblob,  `blob_col`"
+            + " blob,  `mediumblob_col` mediumblob,  `longblob_col` longblob,  `tinytext_col`"
+            + " tinytext,  `text_col` text,  `mediumtext_col` mediumtext,  `longtext_col`"
+            + " longtext)");
+    stmt.execute("CREATE TABLE IF NOT EXISTS ytab(y year)");
+    stmt.execute(
+        "CREATE TABLE IF NOT EXISTS maxcharlength(maxcharlength char(1)) character set utf8");
+    stmt.execute("CREATE TABLE IF NOT EXISTS conj72(t tinyint(1))");
+    if (isMariaDBServer() && minVersion(10, 3, 4)) {
+      stmt.execute("CREATE TABLE IF NOT EXISTS versionTable(x INT) WITH SYSTEM VERSIONING");
+    }
+    stmt.execute("drop table if exists cross3");
+    stmt.execute("drop table if exists cross2");
+    stmt.execute("drop table if exists cross1");
+    stmt.execute("create table cross1 (id int not null primary key, val varchar(20))");
+    stmt.execute(
+        "create table cross2 (id int not null, id2 int not null,  id_ref0 int, foreign key"
+            + " (id_ref0) references cross1(id), UNIQUE unik_name (id, id2))");
+    stmt.execute(
+        "create table cross3 (id int not null primary key, id_ref1 int, id_ref2 int, foreign key"
+            + " fk_my_name (id_ref1, id_ref2) references cross2(id, id2) on update cascade)");
+    stmt.execute(
+        "create table getBestRowIdentifier1(i int not null primary key auto_increment, id int,"
+            + " id_ref1 int, id_ref2 int, foreign key fk_my_name_1 (id_ref1, id_ref2) references"
+            + " cross2(id, id2) on update cascade, UNIQUE getBestRowIdentifier_unik (id))");
+    stmt.execute(
+        "create table getBestRowIdentifier2(id_ref0 int not null, id_ref1 int, id_ref2 int not"
+            + " null, UNIQUE (id_ref1, id_ref2) , UNIQUE (id_ref0, id_ref2))");
+    stmt.execute(
+        "CREATE TABLE IF NOT EXISTS get_index_info(\n"
+            + "    no INT NOT NULL AUTO_INCREMENT,\n"
+            + "    product_category INT NOT NULL,\n"
+            + "    product_id INT NOT NULL,\n"
+            + "    customer_id INT NOT NULL,\n"
+            + "    PRIMARY KEY(no),\n"
+            + "    INDEX ind_prod (product_category, product_id),\n"
+            + "    INDEX ind_cust (customer_id))");
+    stmt.execute(
+        "create table text_types_text (varchar100           varchar(100),\n"
+            + "  varchar255           varchar(255),\n"
+            + "  text                 text,\n"
+            + "  `tinytext`           tinytext,\n"
+            + "  `mediumtext`         mediumtext,\n"
+            + "  `longtext`           longtext)");
+  }
+
+  private static void checkType(String name, int actualType, String colName, int expectedType) {
+    if (name.equals(colName)) {
+      assertEquals(actualType, expectedType);
+    }
+  }
+
+  @Test
+  public void primaryKeysTest() throws SQLException {
+    DatabaseMetaData meta = sharedConn.getMetaData();
+    ResultSet rs = meta.getPrimaryKeys(sharedConn.getCatalog(), null, "dbpk_test");
+    int counter = 0;
+    while (rs.next()) {
+      counter++;
+      assertEquals(sharedConn.getCatalog(), rs.getString("table_cat"));
+      assertEquals(null, rs.getString("table_schem"));
+      assertEquals("dbpk_test", rs.getString("table_name"));
+      assertEquals("id" + counter, rs.getString("column_name"));
+      assertEquals("id" + counter, rs.getString("column_name"));
+      assertEquals("PRIMARY", rs.getString("PK_NAME"));
+    }
+    assertEquals(2, counter);
+  }
+
+  @Test
+  public void primaryKeyTest2() throws SQLException {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    stmt.execute("drop table if exists primarykeytest2");
+    stmt.execute("drop table if exists primarykeytest1");
+    stmt.execute("CREATE TABLE primarykeytest1 ( id1 integer, constraint pk primary key(id1))");
+    stmt.execute(
+        "CREATE TABLE primarykeytest2 (id2a integer, id2b integer, constraint pk primary key(id2a,"
+            + " id2b), constraint fk1 foreign key(id2a) references primarykeytest1(id1), "
+            + " constraint fk2 foreign key(id2b) references primarykeytest1(id1))");
+
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getPrimaryKeys(sharedConn.getCatalog(), null, "primarykeytest2");
+    int counter = 0;
+    while (rs.next()) {
+      counter++;
+      assertEquals(sharedConn.getCatalog(), rs.getString("table_cat"));
+      assertEquals(null, rs.getString("table_schem"));
+      assertEquals("primarykeytest2", rs.getString("table_name"));
+      assertEquals(counter, rs.getShort("key_seq"));
+      assertEquals("PRIMARY", rs.getString("pk_name"));
+    }
+    assertEquals(2, counter);
+    stmt.execute("drop table if exists primarykeytest2");
+    stmt.execute("drop table if exists primarykeytest1");
+  }
+
+  @Test
+  public void datetimeTest() throws SQLException {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("select * from datetime_test");
+    assertEquals(93, rs.getMetaData().getColumnType(1));
+  }
+
+  @Test
+  public void functionColumns() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    DatabaseMetaData meta = sharedConn.getMetaData();
+
+    if (meta.getDatabaseMajorVersion() < 5) {
+      return;
+    } else if (meta.getDatabaseMajorVersion() == 5 && meta.getDatabaseMinorVersion() < 5) {
+      return;
+    }
+
+    stmt.execute("DROP FUNCTION IF EXISTS hello");
+    stmt.execute(
+        "CREATE FUNCTION hello (s CHAR(20), i int) RETURNS CHAR(50) DETERMINISTIC  "
+            + "RETURN CONCAT('Hello, ',s,'!')");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs = meta.getFunctionColumns(null, null, "hello", null);
+
+    assertTrue(rs.next());
+    /* First row is for return value */
+    assertEquals(rs.getString("FUNCTION_CAT"), sharedConn.getCatalog());
+    assertEquals(rs.getString("FUNCTION_SCHEM"), null);
+    assertEquals(rs.getString("COLUMN_NAME"), null); /* No name, since it is return value */
+    assertEquals(rs.getInt("COLUMN_TYPE"), DatabaseMetaData.functionReturn);
+    assertEquals(rs.getInt("DATA_TYPE"), Types.CHAR);
+    assertEquals(rs.getString("TYPE_NAME"), "char");
+
+    assertTrue(rs.next());
+    assertEquals(rs.getString("COLUMN_NAME"), "s"); /* input parameter 's' (CHAR) */
+    assertEquals(rs.getInt("COLUMN_TYPE"), DatabaseMetaData.functionColumnIn);
+    assertEquals(rs.getInt("DATA_TYPE"), Types.CHAR);
+    assertEquals(rs.getString("TYPE_NAME"), "char");
+
+    assertTrue(rs.next());
+    assertEquals(rs.getString("COLUMN_NAME"), "i"); /* input parameter 'i' (INT) */
+    assertEquals(rs.getInt("COLUMN_TYPE"), DatabaseMetaData.functionColumnIn);
+    assertEquals(rs.getInt("DATA_TYPE"), Types.INTEGER);
+    assertEquals(rs.getString("TYPE_NAME"), "int");
+    stmt.execute("DROP FUNCTION IF EXISTS hello");
+  }
+
+  /** Same as getImportedKeys, with one foreign key in a table in another catalog. */
+  @Test
+  public void getImportedKeys() throws Exception {
+    getImportedKeys(sharedConn, true);
+    try (org.mariadb.jdbc.Connection con = createCon()) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("SET sql_mode = concat(@@sql_mode,',NO_BACKSLASH_ESCAPES')");
+      getImportedKeys(con, true);
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("importedKeysWithConstraintNames=false")) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("SET sql_mode = concat(@@sql_mode,',NO_BACKSLASH_ESCAPES')");
+      getImportedKeys(con, false);
+    }
+  }
+
+  private void getImportedKeys(
+      org.mariadb.jdbc.Connection con, boolean importedKeysWithConstraintNames) throws Exception {
+    // cancel for MySQL 8.0, since CASCADE with I_S give importedKeySetDefault, not
+    // importedKeyCascade
+    //    Assumptions.assumeFalse(!isMariaDBServer() && minVersion(8, 0, 0));
+    Assumptions.assumeFalse(isXpand());
+    java.sql.Statement st = con.createStatement();
+    st.execute("DROP TABLE IF EXISTS `product order 1`");
+    st.execute("DROP TABLE IF EXISTS `other sch'ema`.`product order.2`");
+    st.execute("DROP DATABASE IF EXISTS `other sch'ema`");
+    st.execute("DROP TABLE IF EXISTS `product_order.3`");
+    st.execute("DROP TABLE IF EXISTS product_order4");
+    st.execute("DROP TABLE IF EXISTS t1.product ");
+    st.execute("DROP TABLE IF EXISTS `cus``tomer`");
+    st.execute("DROP DATABASE IF EXISTS test1");
+
+    st.execute("CREATE DATABASE IF NOT EXISTS t1");
+    st.execute("CREATE DATABASE IF NOT EXISTS `other sch'ema`");
+
+    st.execute(
+        "CREATE TABLE t1.product ( category INT NOT NULL, id INT NOT NULL, price DECIMAL,"
+            + " UNIQUE unik_name (category, id) )");
+
+    st.execute(
+        "CREATE TABLE `cus``tomer` (id INT NOT NULL, id2 INT NOT NULL, PRIMARY KEY (id), UNIQUE"
+            + " unikConst (id2))");
+    String constraint = "ON UPDATE SET DEFAULT ON DELETE SET DEFAULT";
+    if (!isMariaDBServer() || !minVersion(10, 5, 0))
+      constraint = "ON UPDATE CASCADE ON DELETE CASCADE";
+    st.execute(
+        "CREATE TABLE `product order 1` (\n"
+            + "    no INT NOT NULL AUTO_INCREMENT,\n"
+            + "    product_category INT NOT NULL,\n"
+            + "    product_id INT NOT NULL,\n"
+            + "    customer_id INT DEFAULT NULL,\n"
+            + "    PRIMARY KEY(no),\n"
+            + "    INDEX (product_category, product_id),\n"
+            + "    INDEX (customer_id),\n"
+            + "    FOREIGN KEY (product_category, product_id)\n"
+            + "      REFERENCES t1.product(category, id)\n"
+            + "      ON UPDATE CASCADE ON DELETE CASCADE,\n"
+            + "    FOREIGN KEY (customer_id)\n"
+            + "      REFERENCES `cus``tomer`(id)\n"
+            + constraint
+            + ")");
+
+    st.execute(
+        "CREATE TABLE `other sch'ema`.`product order.2` (\n"
+            + "    no INT NOT NULL,\n"
+            + "    customer_id INT,\n"
+            + "    FOREIGN KEY (customer_id)\n"
+            + "      REFERENCES "
+            + sharedConn.getCatalog()
+            + ".`cus``tomer`(id)\n"
+            + "      ON UPDATE RESTRICT ON DELETE RESTRICT)");
+
+    st.execute(
+        "CREATE TABLE `product_order.3` (\n"
+            + "    no INT NOT NULL,\n"
+            + "    customer_id INT,\n"
+            + "    FOREIGN KEY (customer_id)\n"
+            + "      REFERENCES `cus``tomer`(id)\n"
+            + "      ON UPDATE SET NULL ON DELETE SET NULL)");
+
+    st.execute(
+        "CREATE TABLE product_order4 (\n"
+            + "    no INT NOT NULL,\n"
+            + "    customer_id INT,\n"
+            + "    customer_id2 INT,\n"
+            + "    FOREIGN KEY fk1 (customer_id)\n"
+            + "      REFERENCES `cus``tomer`(id)\n"
+            + "      ON UPDATE NO ACTION ON DELETE NO ACTION,"
+            + "    FOREIGN KEY fk2 (customer_id2)\n"
+            + "      REFERENCES `cus``tomer`(id2)\n"
+            + "      ON UPDATE SET NULL ON DELETE SET NULL)");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> con.getMetaData().getImportedKeys(con.getCatalog(), null, null),
+        "'table' parameter in getImportedKeys cannot be null");
+    /*
+    Test that I_S implementation is equivalent to parsing "show create table" .
+     Get result sets using either method and compare (ignore minor differences INT vs SMALLINT
+    */
+    ResultSet rs1 =
+        con.getMetaData().getImportedKeysUsingShowCreateTable(con.getCatalog(), "product order 1");
+    ResultSet rs2 =
+        con.getMetaData()
+            .getImportedKeysUsingInformationSchema(con.getCatalog(), "product order 1");
+    assertEquals(rs1.getMetaData().getColumnCount(), rs2.getMetaData().getColumnCount());
+    for (int i = 0; i < 2; i++) {
+      ResultSet rs = i == 0 ? rs1 : rs2;
+      assertTrue(rs.next());
+
+      assertEquals("t1", rs.getString("PKTABLE_CAT"));
+      assertEquals(null, rs.getString("PKTABLE_SCHEM"));
+      assertEquals("product", rs.getString("PKTABLE_NAME"));
+      assertEquals("category", rs.getString("PKCOLUMN_NAME"));
+      assertEquals(sharedConn.getCatalog(), rs.getString("FKTABLE_CAT"));
+      assertEquals(null, rs.getString("FKTABLE_SCHEM"));
+      assertEquals("product order 1", rs.getString("FKTABLE_NAME"));
+      assertEquals("product_category", rs.getString("FKCOLUMN_NAME"));
+      assertEquals(1, rs.getInt("KEY_SEQ"));
+      assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("DELETE_RULE"));
+      assertEquals("product order 1_ibfk_1", rs.getString("FK_NAME"));
+      // with show, meta don't know contraint name
+      assertEquals(
+          (i == 0 && !importedKeysWithConstraintNames) ? null : "unik_name",
+          rs.getString("PK_NAME"));
+      assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY"));
+
+      assertTrue(rs.next());
+      assertEquals("t1", rs.getString("PKTABLE_CAT"));
+      assertEquals(null, rs.getString("PKTABLE_SCHEM"));
+      assertEquals("product", rs.getString("PKTABLE_NAME"));
+      assertEquals("id", rs.getString("PKCOLUMN_NAME"));
+      assertEquals(sharedConn.getCatalog(), rs.getString("FKTABLE_CAT"));
+      assertEquals(null, rs.getString("FKTABLE_SCHEM"));
+      assertEquals("product order 1", rs.getString("FKTABLE_NAME"));
+      assertEquals("product_id", rs.getString("FKCOLUMN_NAME"));
+      assertEquals(2, rs.getInt("KEY_SEQ"));
+      assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("DELETE_RULE"));
+      assertEquals("product order 1_ibfk_1", rs.getString("FK_NAME"));
+      // with show, meta don't know contraint name
+      assertEquals(
+          (i == 0 && !importedKeysWithConstraintNames) ? null : "unik_name",
+          rs.getString("PK_NAME"));
+      assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY"));
+
+      assertTrue(rs.next());
+      assertEquals(sharedConn.getCatalog(), rs.getString("PKTABLE_CAT"));
+      assertEquals(null, rs.getString("PKTABLE_SCHEM"));
+      assertEquals("cus`tomer", rs.getString("PKTABLE_NAME"));
+      assertEquals("id", rs.getString("PKCOLUMN_NAME"));
+      assertEquals(sharedConn.getCatalog(), rs.getString("FKTABLE_CAT"));
+      assertEquals(null, rs.getString("FKTABLE_SCHEM"));
+      assertEquals("product order 1", rs.getString("FKTABLE_NAME"));
+      assertEquals("customer_id", rs.getString("FKCOLUMN_NAME"));
+      assertEquals(1, rs.getInt("KEY_SEQ"));
+      if (isMariaDBServer() && minVersion(10, 5, 0)) {
+        assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE"));
+        assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+      } else {
+        assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("UPDATE_RULE"));
+        assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("DELETE_RULE"));
+      }
+      assertEquals("product order 1_ibfk_2", rs.getString("FK_NAME"));
+      // with show, meta don't know contraint name
+      assertEquals(
+          (i == 0 && !importedKeysWithConstraintNames) ? null : "PRIMARY", rs.getString("PK_NAME"));
+      assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY"));
+    }
+
+    /* Also compare metadata */
+    ResultSetMetaData md1 = rs1.getMetaData();
+    ResultSetMetaData md2 = rs2.getMetaData();
+    for (int i = 1; i <= md1.getColumnCount(); i++) {
+      assertEquals(md1.getColumnLabel(i), md2.getColumnLabel(i));
+    }
+
+    rs1 = con.getMetaData().getImportedKeysUsingShowCreateTable("other sch'ema", "product order.2");
+    rs2 =
+        con.getMetaData().getImportedKeysUsingInformationSchema("other sch'ema", "product order.2");
+    assertEquals(rs1.getMetaData().getColumnCount(), rs2.getMetaData().getColumnCount());
+    for (int i = 0; i < 2; i++) {
+      ResultSet rs = i == 0 ? rs1 : rs2;
+      assertTrue(rs.next());
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+    }
+
+    rs1 =
+        con.getMetaData()
+            .getImportedKeysUsingShowCreateTable(sharedConn.getCatalog(), "product_order.3");
+    rs2 =
+        con.getMetaData()
+            .getImportedKeysUsingInformationSchema(sharedConn.getCatalog(), "product_order.3");
+    assertEquals(rs1.getMetaData().getColumnCount(), rs2.getMetaData().getColumnCount());
+    for (int i = 0; i < 2; i++) {
+      ResultSet rs = i == 0 ? rs1 : rs2;
+      assertTrue(rs.next());
+      assertEquals(DatabaseMetaData.importedKeySetNull, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeySetNull, rs.getInt("DELETE_RULE"));
+    }
+
+    rs1 =
+        con.getMetaData()
+            .getImportedKeysUsingShowCreateTable(sharedConn.getCatalog(), "product_order4");
+    rs2 =
+        con.getMetaData()
+            .getImportedKeysUsingInformationSchema(sharedConn.getCatalog(), "product_order4");
+    assertEquals(rs1.getMetaData().getColumnCount(), rs2.getMetaData().getColumnCount());
+    for (int i = 0; i < 2; i++) {
+      ResultSet rs = i == 0 ? rs1 : rs2;
+      if (isMariaDBServer()) {
+        for (int j = 0; j < 2; j++) {
+          assertTrue(rs.next());
+          if ("fk1".equals(rs.getString("FK_NAME"))) {
+            assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("UPDATE_RULE"));
+            assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("DELETE_RULE"));
+          } else {
+            assertEquals(DatabaseMetaData.importedKeySetNull, rs.getInt("UPDATE_RULE"));
+            assertEquals(DatabaseMetaData.importedKeySetNull, rs.getInt("DELETE_RULE"));
+          }
+        }
+      }
+    }
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () ->
+            con.getMetaData()
+                .getImportedKeysUsingShowCreateTable(sharedConn.getCatalog(), "UNKNO>NTABLE"),
+        " doesn't exist");
+
+    st.execute("DROP TABLE IF EXISTS `product order 1`");
+    st.execute("DROP TABLE IF EXISTS `other sch'ema`.`product order.2`");
+    st.execute("DROP TABLE IF EXISTS `product_order.3`");
+    st.execute("DROP TABLE IF EXISTS product_order4");
+    st.execute("DROP TABLE IF EXISTS t1.product ");
+    st.execute("DROP TABLE IF EXISTS `cus``tomer`");
+    st.execute("DROP DATABASE IF EXISTS test1");
+    st.execute("DROP DATABASE IF EXISTS `other sch'ema`");
+  }
+
+  @Test
+  public void exportedKeysTest() throws SQLException {
+
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getExportedKeys(sharedConn.getCatalog(), null, "cross%");
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString("PKTABLE_CAT"));
+    assertEquals(null, rs.getString("PKTABLE_SCHEM"));
+    assertEquals("cross1", rs.getString("PKTABLE_NAME"));
+    assertEquals("id", rs.getString("PKCOLUMN_NAME"));
+    assertEquals(sharedConn.getCatalog(), rs.getString("FKTABLE_CAT"));
+    assertEquals(null, rs.getString("FKTABLE_SCHEM"));
+    assertEquals("cross2", rs.getString("FKTABLE_NAME"));
+    assertEquals("id_ref0", rs.getString("FKCOLUMN_NAME"));
+    assertTrue(rs.getInt("KEY_SEQ") == 1 || rs.wasNull());
+    if (!isMariaDBServer() && minVersion(8, 0, 0)) {
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("DELETE_RULE"));
+    } else {
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+    }
+    assertEquals("cross2_ibfk_1", rs.getString("FK_NAME"));
+    assertTrue(
+        "PRIMARY".equals(rs.getString("PK_NAME"))
+            || "__idx_cross1__PRIMARY".equals(rs.getString("PK_NAME")));
+
+    assertTrue(rs.next());
+
+    assertEquals(sharedConn.getCatalog(), rs.getString("PKTABLE_CAT"));
+    assertEquals(null, rs.getString("PKTABLE_SCHEM"));
+    assertEquals("cross2", rs.getString("PKTABLE_NAME"));
+    assertEquals("id", rs.getString("PKCOLUMN_NAME"));
+    assertEquals(sharedConn.getCatalog(), rs.getString("FKTABLE_CAT"));
+    assertEquals(null, rs.getString("FKTABLE_SCHEM"));
+    assertEquals("cross3", rs.getString("FKTABLE_NAME"));
+    assertEquals("id_ref1", rs.getString("FKCOLUMN_NAME"));
+    assertTrue(rs.getInt("KEY_SEQ") == 1 || rs.wasNull());
+    assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("UPDATE_RULE"));
+    if (!isMariaDBServer() && minVersion(8, 0, 0)) {
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("DELETE_RULE"));
+    } else {
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+    }
+    assertTrue(
+        "cross3_ibfk_1".equals(rs.getString("FK_NAME"))
+            || "fk_my_name".equals(rs.getString("FK_NAME")));
+    assertEquals("unik_name", rs.getString("PK_NAME"));
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString("PKTABLE_CAT"));
+    assertEquals(null, rs.getString("PKTABLE_SCHEM"));
+    assertEquals("cross2", rs.getString("PKTABLE_NAME"));
+    assertEquals("id2", rs.getString("PKCOLUMN_NAME"));
+    assertEquals(sharedConn.getCatalog(), rs.getString("FKTABLE_CAT"));
+    assertEquals(null, rs.getString("FKTABLE_SCHEM"));
+    assertEquals("cross3", rs.getString("FKTABLE_NAME"));
+    assertEquals("id_ref2", rs.getString("FKCOLUMN_NAME"));
+    assertTrue(rs.getInt("KEY_SEQ") == 2 || rs.wasNull());
+    assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt("UPDATE_RULE"));
+    if (!isMariaDBServer() && minVersion(8, 0, 0)) {
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("DELETE_RULE"));
+    } else {
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+    }
+    assertTrue(
+        "fk_my_name".equals(rs.getString("FK_NAME"))
+            || "cross3_ibfk_1".equals(rs.getString("FK_NAME")));
+    assertEquals("unik_name", rs.getString("PK_NAME"));
+  }
+
+  @Test
+  public void importedKeysTest() throws SQLException {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    stmt.execute("drop table if exists fore_key0");
+    stmt.execute("drop table if exists fore_key1");
+    stmt.execute("drop table if exists prim_key");
+
+    stmt.execute(
+        "create table prim_key (id int not null primary key, " + "val varchar(20)) engine=innodb");
+    stmt.execute(
+        "create table fore_key0 (id int not null primary key, "
+            + "id_ref0 int, foreign key (id_ref0) references prim_key(id)) engine=innodb");
+    stmt.execute(
+        "create table fore_key1 (id int not null primary key, id_ref1 int, foreign key (id_ref1)"
+            + " references prim_key(id) on update cascade) engine=innodb");
+
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getImportedKeys(sharedConn.getCatalog(), null, "fore_key0");
+    int counter = 0;
+    while (rs.next()) {
+      assertEquals("id", rs.getString("pkcolumn_name"));
+      assertEquals("prim_key", rs.getString("pktable_name"));
+      counter++;
+    }
+    assertEquals(1, counter);
+    stmt.execute("drop table if exists fore_key0");
+    stmt.execute("drop table if exists fore_key1");
+    stmt.execute("drop table if exists prim_key");
+  }
+
+  @Test
+  public void testGetCatalogs() throws SQLException {
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+
+    ResultSet rs = dbmd.getCatalogs();
+    boolean haveMysql = false;
+    boolean haveInformationSchema = false;
+    while (rs.next()) {
+      String cat = rs.getString(1);
+
+      if (cat.equalsIgnoreCase("mysql")) {
+        haveMysql = true;
+      } else if (cat.equalsIgnoreCase("information_schema")) {
+        haveInformationSchema = true;
+      }
+    }
+    if (!isXpand()) assertTrue(haveMysql);
+    assertTrue(haveInformationSchema);
+  }
+
+  @Test
+  public void testGetTables() throws SQLException {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    stmt.execute("drop table if exists fore_key0");
+    stmt.execute("drop table if exists fore_key1");
+    stmt.execute("drop table if exists prim_key");
+
+    stmt.execute(
+        "create table prim_key (id int not null primary key, " + "val varchar(20)) engine=innodb");
+    stmt.execute(
+        "create table fore_key0 (id int not null primary key, "
+            + "id_ref0 int, foreign key (id_ref0) references prim_key(id)) engine=innodb");
+    stmt.execute(
+        "create table fore_key1 (id int not null primary key, id_ref1 int, foreign key (id_ref1)"
+            + " references prim_key(id) on update cascade) engine=innodb");
+
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getTables(null, null, "prim_key", null);
+
+    assertEquals(true, rs.next());
+    rs = dbmd.getTables("", null, "prim_key", null);
+    assertEquals(true, rs.next());
+
+    rs = dbmd.getTables("", null, "prim_key", new String[] {"BASE TABLE", "OTHER"});
+    assertEquals(true, rs.next());
+
+    rs = dbmd.getTables("", null, "prim_key", new String[] {"TABLE", null});
+    assertEquals(true, rs.next());
+
+    // ensure no regression CONJ-921
+    rs = dbmd.getTables(null, null, null, new String[] {"TABLE"});
+    assertEquals(true, rs.next());
+  }
+
+  @Test
+  public void testGetTables2() throws SQLException {
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    Assumptions.assumeTrue(!isXpand());
+    ResultSet rs =
+        dbmd.getTables(
+            "information_schema", null, "TABLE_PRIVILEGES", new String[] {"SYSTEM VIEW"});
+    assertEquals(true, rs.next());
+    assertEquals(false, rs.next());
+    rs = dbmd.getTables(null, null, "TABLE_PRIVILEGES", new String[] {"TABLE"});
+    assertEquals(false, rs.next());
+  }
+
+  @Test
+  public void testGetTablesSystemVersionTables() throws SQLException {
+    Assumptions.assumeTrue(isMariaDBServer() && minVersion(10, 3, 4));
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getTables(null, null, "versionTable", null);
+    assertEquals(true, rs.next());
+    assertEquals(false, rs.next());
+    rs = dbmd.getTables(null, null, "versionTable", new String[] {"TABLE"});
+    assertEquals(true, rs.next());
+    assertEquals(false, rs.next());
+    rs = dbmd.getTables(null, null, "versionTable", new String[] {"SYSTEM VIEW"});
+    assertEquals(false, rs.next());
+  }
+
+  @Test
+  public void testGetTables3() throws SQLException {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    stmt.execute("drop table if exists table_type_test");
+
+    stmt.execute(
+        "create table table_type_test (id int not null primary key, "
+            + "val varchar(20)) engine=innodb");
+
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet tableSet = dbmd.getTables(null, null, "table_type_test", null);
+
+    assertEquals(true, tableSet.next());
+
+    String tableName = tableSet.getString("TABLE_NAME");
+    assertEquals("table_type_test", tableName);
+
+    String tableType = tableSet.getString("TABLE_TYPE");
+    assertEquals("TABLE", tableType);
+    // see for possible values
+    // https://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTableTypes%28%29
+  }
+
+  @Test
+  public void testGetColumns() throws SQLException {
+    // mysql 5.6 doesn't permit VIRTUAL keyword
+    Assumptions.assumeTrue(isMariaDBServer() || !isMariaDBServer() && minVersion(5, 7, 0));
+    // Xpand doesn't support PERSISTENT keyword
+    Assumptions.assumeFalse(isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+    if (minVersion(10, 2, 0) || !isMariaDBServer()) {
+      stmt.execute(
+          "CREATE TABLE IF NOT EXISTS `ta\n"
+              + "ble'getcolumns`(a INT NOT NULL primary key auto_increment, b VARCHAR(32), c INT AS"
+              + " (CHAR_LENGTH(b)) VIRTUAL, d VARCHAR(5) AS (left(b,5)) STORED) CHARACTER SET"
+              + " 'utf8mb4'");
+    } else {
+      stmt.execute(
+          "CREATE TABLE IF NOT EXISTS `ta\n"
+              + "ble'getcolumns`(a INT NOT NULL primary key auto_increment, b VARCHAR(32), c INT AS"
+              + " (CHAR_LENGTH(b)) VIRTUAL, d VARCHAR(5) AS (left(b,5)) PERSISTENT) CHARACTER SET"
+              + " 'utf8mb4'");
+    }
+
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getColumns(null, null, "ta\nble'getcolumns", null);
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1)); // TABLE_CAT
+    assertEquals(null, rs.getString(2)); // TABLE_SCHEM
+    assertEquals("ta\nble'getcolumns", rs.getString(3)); // TABLE_NAME
+    assertEquals("a", rs.getString(4)); // COLUMN_NAME
+    assertEquals(Types.INTEGER, rs.getInt(5)); // DATA_TYPE
+    assertEquals("INT", rs.getString(6)); // "TYPE_NAME
+    assertEquals(10, rs.getInt(7)); // "COLUMN_SIZE
+    assertEquals(0, rs.getInt(9)); // DECIMAL_DIGITS
+    assertEquals(10, rs.getInt(10)); // NUM_PREC_RADIX
+    assertEquals(0, rs.getInt(11)); // NULLABLE
+    assertEquals("", rs.getString(12)); // REMARKS
+    assertEquals(null, rs.getString(13)); // COLUMN_DEF
+    assertEquals(0, rs.getInt(16)); // CHAR_OCTET_LENGTH
+    assertEquals(1, rs.getInt(17)); // ORDINAL_POSITION
+    assertEquals("NO", rs.getString(18)); // IS_NULLABLE
+    assertEquals(null, rs.getString(19)); // SCOPE_CATALOG
+    assertEquals(null, rs.getString(20)); // SCOPE_SCHEMA
+    assertEquals(null, rs.getString(21)); // SCOPE_TABLE
+    assertEquals(0, rs.getShort(22)); // SOURCE_DATA_TYPE
+    assertEquals("YES", rs.getString(23)); // IS_AUTOINCREMENT
+    assertEquals("NO", rs.getString(24)); // IS_GENERATEDCOLUMN
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1)); // TABLE_CAT
+    assertEquals(null, rs.getString(2)); // TABLE_SCHEM
+    assertEquals("ta\nble'getcolumns", rs.getString(3)); // TABLE_NAME
+    assertEquals("b", rs.getString(4)); // COLUMN_NAME
+    assertEquals(Types.VARCHAR, rs.getInt(5)); // DATA_TYPE
+    assertEquals("VARCHAR", rs.getString(6)); // "TYPE_NAME
+    assertEquals(32, rs.getInt(7)); // "COLUMN_SIZE
+    assertEquals(0, rs.getInt(9)); // DECIMAL_DIGITS
+    assertEquals(10, rs.getInt(10)); // NUM_PREC_RADIX
+    assertEquals(1, rs.getInt(11)); // NULLABLE
+    assertEquals("", rs.getString(12)); // REMARKS
+
+    // since 10.2.7, value that are expected as String are enclosed with single quotes as javadoc
+    // require
+    assertTrue("null".equalsIgnoreCase(rs.getString(13)) || rs.getString(13) == null); // COLUMN_DEF
+    assertEquals(32 * 4, rs.getInt(16)); // CHAR_OCTET_LENGTH
+    assertEquals(2, rs.getInt(17)); // ORDINAL_POSITION
+    assertEquals("YES", rs.getString(18)); // IS_NULLABLE
+    assertEquals(null, rs.getString(19)); // SCOPE_CATALOG
+    assertEquals(null, rs.getString(20)); // SCOPE_SCHEMA
+    assertEquals(null, rs.getString(21)); // SCOPE_TABLE
+    assertEquals(0, rs.getShort(22)); // SOURCE_DATA_TYPE
+    assertEquals("NO", rs.getString(23)); // IS_AUTOINCREMENT
+    assertEquals("NO", rs.getString(24)); // IS_GENERATEDCOLUMN
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1)); // TABLE_CAT
+    assertEquals(null, rs.getString(2)); // TABLE_SCHEM
+    assertEquals("ta\nble'getcolumns", rs.getString(3)); // TABLE_NAME
+    assertEquals("c", rs.getString(4)); // COLUMN_NAME
+    assertEquals(Types.INTEGER, rs.getInt(5)); // DATA_TYPE
+    assertEquals("INT", rs.getString(6)); // "TYPE_NAME
+    assertEquals(10, rs.getInt(7)); // "COLUMN_SIZE
+    assertEquals(0, rs.getInt(9)); // DECIMAL_DIGITS
+    assertEquals(10, rs.getInt(10)); // NUM_PREC_RADIX
+    assertEquals(1, rs.getInt(11)); // NULLABLE
+    assertEquals("", rs.getString(12)); // REMARKS
+
+    // since 10.2.7, value that are expected as String are enclosed with single quotes as javadoc
+    // require
+    assertTrue("null".equalsIgnoreCase(rs.getString(13)) || rs.getString(13) == null); // COLUMN_DEF
+
+    assertEquals(0, rs.getInt(16)); // CHAR_OCTET_LENGTH
+    assertEquals(3, rs.getInt(17)); // ORDINAL_POSITION
+    assertEquals("YES", rs.getString(18)); // IS_NULLABLE
+    assertEquals(null, rs.getString(19)); // SCOPE_CATALOG
+    assertEquals(null, rs.getString(20)); // SCOPE_SCHEMA
+    assertEquals(null, rs.getString(21)); // SCOPE_TABLE
+    assertEquals(0, rs.getShort(22)); // SOURCE_DATA_TYPE
+    assertEquals("NO", rs.getString(23)); // IS_AUTOINCREMENT
+    assertEquals("YES", rs.getString(24)); // IS_GENERATEDCOLUMN
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1)); // TABLE_CAT
+    assertEquals(null, rs.getString(2)); // TABLE_SCHEM
+    assertEquals("ta\nble'getcolumns", rs.getString(3)); // TABLE_NAME
+    assertEquals("d", rs.getString(4)); // COLUMN_NAME
+    assertEquals(Types.VARCHAR, rs.getInt(5)); // DATA_TYPE
+    assertEquals("VARCHAR", rs.getString(6)); // "TYPE_NAME
+    assertEquals(5, rs.getInt(7)); // "COLUMN_SIZE
+    assertEquals(0, rs.getInt(9)); // DECIMAL_DIGITS
+    assertEquals(10, rs.getInt(10)); // NUM_PREC_RADIX
+    assertEquals(1, rs.getInt(11)); // NULLABLE
+    assertEquals("", rs.getString(12)); // REMARKS
+    // since 10.2.7, value that are expected as String are enclosed with single quotes as javadoc
+    // require
+    assertTrue("null".equalsIgnoreCase(rs.getString(13)) || rs.getString(13) == null); // COLUMN_DEF
+    assertEquals(5 * 4, rs.getInt(16)); // CHAR_OCTET_LENGTH
+    assertEquals(4, rs.getInt(17)); // ORDINAL_POSITION
+    assertEquals("YES", rs.getString(18)); // IS_NULLABLE
+    assertEquals(null, rs.getString(19)); // SCOPE_CATALOG
+    assertEquals(null, rs.getString(20)); // SCOPE_SCHEMA
+    assertEquals(null, rs.getString(21)); // SCOPE_TABLE
+    assertEquals(0, rs.getShort(22)); // SOURCE_DATA_TYPE
+    assertEquals("NO", rs.getString(23)); // IS_AUTOINCREMENT
+    assertEquals("YES", rs.getString(24)); // IS_GENERATEDCOLUMN
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void testGetColumnstinyInt1isBit() throws SQLException {
+    try (Connection con = createCon("tinyInt1isBit=false")) {
+      testGetColumnstinyInt1isBit(con);
+    }
+    try (Connection con = createCon("tinyInt1isBit=false")) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("SET sql_mode = concat(@@sql_mode,',NO_BACKSLASH_ESCAPES')");
+      testGetColumnstinyInt1isBit(con);
+    }
+  }
+
+  private void testGetColumnstinyInt1isBit(Connection con) throws SQLException {
+    try {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute(
+          "CREATE TABLE IF NOT EXISTS `tinyInt1\nisBitCols`(id1 tinyint(1), id2 tinyint(2))");
+      stmt.execute("INSERT INTO `tinyInt1\nisBitCols` VALUES (1,2)");
+
+      ResultSet rs1 =
+          sharedConn.createStatement().executeQuery("SELECT * FROM `tinyInt1\nisBitCols`");
+      assertTrue(rs1.next());
+      assertEquals(Boolean.TRUE, rs1.getObject(1));
+      assertEquals(2, rs1.getObject(2));
+
+      rs1 = stmt.executeQuery("SELECT * FROM `tinyInt1\nisBitCols`");
+      assertTrue(rs1.next());
+      assertEquals(1, rs1.getObject(1));
+      assertEquals(2, rs1.getObject(2));
+
+      DatabaseMetaData dbmd = sharedConn.getMetaData();
+      ResultSet rs = dbmd.getColumns(null, null, "tinyInt1\nisBitCols", null);
+
+      assertTrue(rs.next());
+      assertEquals(Types.BOOLEAN, rs.getInt(5));
+      assertTrue(rs.next());
+      assertEquals(Types.TINYINT, rs.getInt(5));
+
+      dbmd = con.getMetaData();
+      rs = dbmd.getColumns(null, null, "tinyInt1\nisBitCols", null);
+
+      assertTrue(rs.next());
+      assertEquals(Types.TINYINT, rs.getInt(5));
+      assertTrue(rs.next());
+      assertEquals(Types.TINYINT, rs.getInt(5));
+
+    } finally {
+      con.createStatement().execute("DROP TABLE IF EXISTS `tinyInt1\nisBitCols`");
+    }
+  }
+
+  @Test
+  public void testTransformedBitIsBoolean() throws SQLException {
+    try (Connection con = createCon("tinyInt1isBit=true&transformedBitIsBoolean=true")) {
+      testTransformedBitIsBoolean(con, true, true);
+    }
+    try (Connection con = createCon("tinyInt1isBit=true&transformedBitIsBoolean=false")) {
+      testTransformedBitIsBoolean(con, true, false);
+    }
+    try (Connection con = createCon("tinyInt1isBit=false&transformedBitIsBoolean=true")) {
+      testTransformedBitIsBoolean(con, false, true);
+    }
+    try (Connection con = createCon("transformedBitIsBoolean=true")) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("SET sql_mode = concat(@@sql_mode,',NO_BACKSLASH_ESCAPES')");
+      testTransformedBitIsBoolean(con, true, true);
+    }
+  }
+
+  private void testTransformedBitIsBoolean(
+      Connection con, boolean tinyInt1isBit, boolean transformedBitIsBoolean) throws SQLException {
+    try {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute(
+          "CREATE TABLE IF NOT EXISTS `tinyInt1\nisBitCols`(id1 tinyint(1), id2 tinyint(2))");
+      stmt.execute("INSERT INTO `tinyInt1\nisBitCols` VALUES (1,2)");
+
+      ResultSet rs1 = con.createStatement().executeQuery("SELECT * FROM `tinyInt1\nisBitCols`");
+      assertTrue(rs1.next());
+      if (tinyInt1isBit) {
+        assertEquals(Boolean.TRUE, rs1.getObject(1));
+        assertEquals(2, rs1.getObject(2));
+      } else {
+        assertEquals(1, rs1.getObject(1));
+        assertEquals(2, rs1.getObject(2));
+      }
+
+      ResultSetMetaData rsm = rs1.getMetaData();
+      if (tinyInt1isBit) {
+        if (transformedBitIsBoolean) {
+          assertEquals(Types.BOOLEAN, rsm.getColumnType(1));
+          assertEquals("BOOLEAN", rsm.getColumnTypeName(1));
+        } else {
+          assertEquals(Types.BIT, rsm.getColumnType(1));
+          assertEquals("BIT", rsm.getColumnTypeName(1));
+        }
+      } else {
+        assertEquals(Types.TINYINT, rsm.getColumnType(1));
+        assertEquals("TINYINT", rsm.getColumnTypeName(1));
+      }
+
+      DatabaseMetaData dbmd = con.getMetaData();
+      ResultSet rs = dbmd.getColumns(null, null, "tinyInt1\nisBitCols", null);
+
+      assertTrue(rs.next());
+      if (tinyInt1isBit) {
+        if (transformedBitIsBoolean) {
+          assertEquals(Types.BOOLEAN, rs.getInt(5));
+          assertEquals("BOOLEAN", rs.getString(6));
+        } else {
+          assertEquals(Types.BIT, rs.getInt(5));
+          assertEquals("BIT", rs.getString(6));
+        }
+      } else {
+        assertEquals(Types.TINYINT, rs.getInt(5));
+        assertEquals("TINYINT", rs.getString(6));
+      }
+      assertTrue(rs.next());
+      assertEquals(Types.TINYINT, rs.getInt(5));
+
+    } finally {
+      con.createStatement().execute("DROP TABLE IF EXISTS `tinyInt1\nisBitCols`");
+    }
+  }
+
+  private void testResultSetColumns(ResultSet rs, String spec) throws SQLException {
+    ResultSetMetaData rsmd = rs.getMetaData();
+    String[] tokens = spec.split(",");
+
+    for (int i = 0; i < tokens.length; i++) {
+      String[] splitTokens = tokens[i].trim().split(" ");
+      String label = splitTokens[0];
+      String type = splitTokens[1];
+
+      int col = i + 1;
+      assertEquals(label, rsmd.getColumnLabel(col));
+      int columnType = rsmd.getColumnType(col);
+      switch (type) {
+        case "String":
+          assertTrue(
+              columnType == Types.VARCHAR
+                  || columnType == Types.CHAR
+                  || columnType == Types.NULL
+                  || columnType == Types.LONGVARCHAR,
+              "invalid type "
+                  + columnType
+                  + " for "
+                  + rsmd.getColumnLabel(col)
+                  + ",expected String");
+          break;
+        case "decimal":
+          assertTrue(
+              columnType == Types.DECIMAL,
+              "invalid type  "
+                  + columnType
+                  + "( "
+                  + rsmd.getColumnTypeName(col)
+                  + " ) for "
+                  + rsmd.getColumnLabel(col)
+                  + ",expected decimal");
+          break;
+        case "int":
+        case "short":
+          assertTrue(
+              columnType == Types.BIGINT
+                  || columnType == Types.INTEGER
+                  || columnType == Types.SMALLINT
+                  || columnType == Types.TINYINT,
+              "invalid type  "
+                  + columnType
+                  + "( "
+                  + rsmd.getColumnTypeName(col)
+                  + " ) for "
+                  + rsmd.getColumnLabel(col)
+                  + ",expected numeric");
+
+          break;
+        case "boolean":
+          assertTrue(
+              columnType == Types.BOOLEAN || columnType == Types.BIT,
+              "invalid type  "
+                  + columnType
+                  + "( "
+                  + rsmd.getColumnTypeName(col)
+                  + " ) for "
+                  + rsmd.getColumnLabel(col)
+                  + ",expected boolean");
+
+          break;
+        case "null":
+          assertTrue(
+              columnType == Types.NULL,
+              "invalid type  "
+                  + columnType
+                  + " for "
+                  + rsmd.getColumnLabel(col)
+                  + ",expected null");
+          break;
+        default:
+          fail("invalid type '" + type + "'");
+          break;
+      }
+    }
+  }
+
+  @Test
+  public void getSchemas() throws SQLException {
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getSchemas();
+    assertFalse(rs.next());
+
+    rs = dbmd.getSchemas("*", "*");
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void getAttributesBasic() throws Exception {
+    testResultSetColumns(
+        sharedConn.getMetaData().getAttributes(null, null, null, null),
+        "TYPE_CAT String,TYPE_SCHEM String,TYPE_NAME String,ATTR_NAME String,DATA_TYPE"
+            + " int,ATTR_TYPE_NAME String,ATTR_SIZE int,DECIMAL_DIGITS int,NUM_PREC_RADIX"
+            + " int,NULLABLE int,REMARKS String,ATTR_DEF String,SQL_DATA_TYPE int,SQL_DATETIME_SUB"
+            + " int, CHAR_OCTET_LENGTH int,ORDINAL_POSITION int,IS_NULLABLE String,SCOPE_CATALOG"
+            + " String,SCOPE_SCHEMA String,SCOPE_TABLE String,SOURCE_DATA_TYPE short");
+  }
+
+  @Test
+  public void identifierCaseSensitivity() throws Exception {
+    // https://jira.mariadb.org/browse/XPT-281
+    Assumptions.assumeFalse(isXpand());
+    java.sql.Statement stmt = sharedConn.createStatement();
+    try {
+      if (sharedConn.getMetaData().supportsMixedCaseIdentifiers()) {
+        /* Case-sensitive identifier handling, we can create both t1 and T1 */
+        stmt.execute("create table aB (i int)");
+        stmt.execute("create table AB (i int)");
+        /* Check there is an entry for both T1 and t1 in getTables */
+        ResultSet rs = sharedConn.getMetaData().getTables(null, null, "aB", null);
+        assertTrue(rs.next());
+        assertFalse(rs.next());
+        rs = sharedConn.getMetaData().getTables(null, null, "AB", null);
+        assertTrue(rs.next());
+        assertFalse(rs.next());
+      }
+
+      if (sharedConn.getMetaData().storesMixedCaseIdentifiers()) {
+        /* Case-insensitive, case-preserving */
+        stmt.execute("create table aB (i int)");
+        try {
+          stmt.execute("create table AB (i int)");
+          fail("should not get there, since names are case-insensitive");
+        } catch (SQLException e) {
+          // normal error
+        }
+
+        /* Check that table is stored case-preserving */
+        ResultSet rs = sharedConn.getMetaData().getTables(null, null, "aB%", null);
+        while (rs.next()) {
+          String tableName = rs.getString("TABLE_NAME");
+          if (tableName.length() == 2) {
+            assertEquals("aB", tableName);
+          }
+        }
+
+        rs = sharedConn.getMetaData().getTables(null, null, "AB", null);
+        assertTrue(rs.next());
+        assertFalse(rs.next());
+      }
+
+      if (sharedConn.getMetaData().storesLowerCaseIdentifiers()) {
+        /* case-insensitive, identifiers converted to lowercase */
+        /* Case-insensitive, case-preserving */
+        stmt.execute("create table aB (i int)");
+        try {
+          stmt.execute("create table AB (i int)");
+          fail("should not get there, since names are case-insensitive");
+        } catch (SQLException e) {
+          // normal error
+        }
+
+        /* Check that table is stored lowercase */
+        ResultSet rs = sharedConn.getMetaData().getTables(null, null, "aB%", null);
+        while (rs.next()) {
+          String tableName = rs.getString("TABLE_NAME");
+          if (tableName.length() == 2) {
+            assertEquals("ab", tableName);
+          }
+        }
+
+        rs = sharedConn.getMetaData().getTables(null, null, "AB", null);
+        assertTrue(rs.next());
+        assertFalse(rs.next());
+      }
+      assertFalse(sharedConn.getMetaData().storesUpperCaseIdentifiers());
+    } finally {
+      try {
+        stmt.execute("DROP TABLE aB");
+      } catch (SQLException sqle) {
+        // ignore
+      }
+      try {
+        stmt.execute("DROP TABLE AB");
+      } catch (SQLException sqle) {
+        // ignore
+      }
+    }
+  }
+
+  @Test
+  public void getBestRowIdentifier() throws SQLException {
+    Assumptions.assumeFalse(isXpand());
+    DatabaseMetaData meta = sharedConn.getMetaData();
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> meta.getBestRowIdentifier(null, null, null, 0, true),
+        "'table' parameter cannot be null in getBestRowIdentifier()");
+    testResultSetColumns(
+        meta.getBestRowIdentifier(null, null, "", 0, true),
+        "SCOPE short,COLUMN_NAME String,DATA_TYPE int, TYPE_NAME String,"
+            + "COLUMN_SIZE int,BUFFER_LENGTH int,"
+            + "DECIMAL_DIGITS short,PSEUDO_COLUMN short");
+
+    ResultSet rs = meta.getBestRowIdentifier(null, null, "cross1", 0, true);
+    assertTrue(rs.next());
+
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowSession, rs.getInt(1));
+    assertEquals("id", rs.getString(2));
+    assertEquals(Types.INTEGER, rs.getInt(3));
+    assertEquals("int", rs.getString(4));
+    assertEquals(10, rs.getInt(5));
+    assertEquals(0, rs.getInt(6));
+    assertEquals(0, rs.getInt(7));
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowNotPseudo, rs.getInt(8));
+    assertFalse(rs.next());
+
+    rs = meta.getBestRowIdentifier(null, null, "cross1", 0, false);
+    assertTrue(rs.next());
+    assertFalse(rs.next());
+
+    rs = meta.getBestRowIdentifier(null, null, "cross2", 0, true);
+    assertTrue(rs.next());
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowSession, rs.getInt(1));
+    assertEquals("id", rs.getString(2));
+    assertEquals(Types.INTEGER, rs.getInt(3));
+    assertEquals("int", rs.getString(4));
+    assertEquals(10, rs.getInt(5));
+    assertEquals(0, rs.getInt(6));
+    assertEquals(0, rs.getInt(7));
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowNotPseudo, rs.getInt(8));
+    assertTrue(rs.next());
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowSession, rs.getInt(1));
+    assertEquals("id2", rs.getString(2));
+    assertEquals(Types.INTEGER, rs.getInt(3));
+    assertEquals("int", rs.getString(4));
+    assertEquals(10, rs.getInt(5));
+    assertEquals(0, rs.getInt(6));
+    assertEquals(0, rs.getInt(7));
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowNotPseudo, rs.getInt(8));
+    assertFalse(rs.next());
+
+    rs = meta.getBestRowIdentifier(null, null, "cross3", 0, true);
+    assertTrue(rs.next());
+
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowSession, rs.getInt(1));
+    assertEquals("id", rs.getString(2));
+    assertEquals(Types.INTEGER, rs.getInt(3));
+    assertEquals("int", rs.getString(4));
+    assertEquals(10, rs.getInt(5));
+    assertEquals(0, rs.getInt(6));
+    assertEquals(0, rs.getInt(7));
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowNotPseudo, rs.getInt(8));
+    assertFalse(rs.next());
+
+    // CHECK using PRI even if exist UNI
+
+    rs = meta.getBestRowIdentifier(null, null, "getBestRowIdentifier1", 0, true);
+    assertTrue(rs.next());
+
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowSession, rs.getInt(1));
+    assertEquals("i", rs.getString(2));
+    assertEquals(Types.INTEGER, rs.getInt(3));
+    assertEquals("int", rs.getString(4));
+    assertEquals(10, rs.getInt(5));
+    assertEquals(0, rs.getInt(6));
+    assertEquals(0, rs.getInt(7));
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowNotPseudo, rs.getInt(8));
+    assertFalse(rs.next());
+
+    rs = meta.getBestRowIdentifier(null, null, "getBestRowIdentifier2", 0, true);
+    assertTrue(rs.next());
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowSession, rs.getInt(1));
+    assertEquals("id_ref0", rs.getString(2));
+    assertEquals(Types.INTEGER, rs.getInt(3));
+    assertEquals("int", rs.getString(4));
+    assertEquals(10, rs.getInt(5));
+    assertEquals(0, rs.getInt(6));
+    assertEquals(0, rs.getInt(7));
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowNotPseudo, rs.getInt(8));
+    assertTrue(rs.next());
+
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowSession, rs.getInt(1));
+    assertEquals("id_ref2", rs.getString(2));
+    assertEquals(Types.INTEGER, rs.getInt(3));
+    assertEquals("int", rs.getString(4));
+    assertEquals(10, rs.getInt(5));
+    assertEquals(0, rs.getInt(6));
+    assertEquals(0, rs.getInt(7));
+    assertEquals(org.mariadb.jdbc.DatabaseMetaData.bestRowNotPseudo, rs.getInt(8));
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void getClientInfoPropertiesBasic() throws Exception {
+    testResultSetColumns(
+        sharedConn.getMetaData().getClientInfoProperties(),
+        "NAME String, MAX_LEN int, DEFAULT_VALUE String, DESCRIPTION String");
+    ResultSet rs = sharedConn.getMetaData().getClientInfoProperties();
+    assertTrue(rs.next());
+    assertEquals("ApplicationName", rs.getString(1));
+    assertEquals(0x00ffffff, rs.getInt(2));
+    assertEquals("", rs.getString(3));
+    assertEquals("The name of the application currently utilizing the connection", rs.getString(4));
+
+    assertTrue(rs.next());
+    assertEquals("ClientUser", rs.getString(1));
+    assertEquals(0x00ffffff, rs.getInt(2));
+    assertEquals("", rs.getString(3));
+    assertEquals(
+        "The name of the user that the application using the connection is performing work for."
+            + " This may not be the same as the user name that was used in establishing the"
+            + " connection.",
+        rs.getString(4));
+
+    assertTrue(rs.next());
+    assertEquals("ClientHostname", rs.getString(1));
+    assertEquals(0x00ffffff, rs.getInt(2));
+    assertEquals("", rs.getString(3));
+    assertEquals(
+        "The hostname of the computer the application using the connection is running on",
+        rs.getString(4));
+
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void getCatalogsBasic() throws SQLException {
+    testResultSetColumns(sharedConn.getMetaData().getCatalogs(), "TABLE_CAT String");
+  }
+
+  @Test
+  public void getColumnsBasic() throws SQLException {
+    Assumptions.assumeFalse(isXpand());
+    cancelForVersion(10, 1); // due to server error MDEV-8984
+    if (minVersion(10, 2, 0)) {
+      testResultSetColumns(
+          sharedConn.getMetaData().getColumns(null, null, null, null),
+          "TABLE_CAT String,TABLE_SCHEM String,TABLE_NAME String,COLUMN_NAME String,"
+              + "DATA_TYPE int,TYPE_NAME String,COLUMN_SIZE decimal,BUFFER_LENGTH int,"
+              + "DECIMAL_DIGITS int,NUM_PREC_RADIX int,NULLABLE int,"
+              + "REMARKS String,COLUMN_DEF String,SQL_DATA_TYPE int,"
+              + "SQL_DATETIME_SUB int, CHAR_OCTET_LENGTH decimal,"
+              + "ORDINAL_POSITION int,IS_NULLABLE String,"
+              + "SCOPE_CATALOG String,SCOPE_SCHEMA String,"
+              + "SCOPE_TABLE String,SOURCE_DATA_TYPE null");
+    } else {
+      testResultSetColumns(
+          sharedConn.getMetaData().getColumns(null, null, null, null),
+          "TABLE_CAT String,TABLE_SCHEM String,TABLE_NAME String,COLUMN_NAME String,"
+              + "DATA_TYPE int,TYPE_NAME String,COLUMN_SIZE int,BUFFER_LENGTH int,"
+              + "DECIMAL_DIGITS int,NUM_PREC_RADIX int,NULLABLE int,"
+              + "REMARKS String,COLUMN_DEF String,SQL_DATA_TYPE int,"
+              + "SQL_DATETIME_SUB int, CHAR_OCTET_LENGTH int,"
+              + "ORDINAL_POSITION int,IS_NULLABLE String,"
+              + "SCOPE_CATALOG String,SCOPE_SCHEMA String,"
+              + "SCOPE_TABLE String,SOURCE_DATA_TYPE null");
+    }
+  }
+
+  @Test
+  public void getProcedureColumnsBasic() throws SQLException {
+    Assumptions.assumeTrue(!isXpand());
+    testResultSetColumns(
+        sharedConn.getMetaData().getProcedureColumns(null, null, null, null),
+        "PROCEDURE_CAT String,PROCEDURE_SCHEM String,PROCEDURE_NAME String,COLUMN_NAME String"
+            + " ,COLUMN_TYPE short,DATA_TYPE int,TYPE_NAME String,PRECISION int,LENGTH int,SCALE"
+            + " short,RADIX short,NULLABLE short,REMARKS String,COLUMN_DEF String,SQL_DATA_TYPE"
+            + " int,SQL_DATETIME_SUB int ,CHAR_OCTET_LENGTH int,ORDINAL_POSITION int,IS_NULLABLE"
+            + " String,SPECIFIC_NAME String");
+  }
+
+  @Test
+  public void getFunctionColumnsBasic() throws SQLException {
+    // https://jira.mariadb.org/browse/XPT-267
+    Assumptions.assumeFalse(isXpand());
+    testResultSetColumns(
+        sharedConn.getMetaData().getFunctionColumns(null, null, null, null),
+        "FUNCTION_CAT String,FUNCTION_SCHEM String,FUNCTION_NAME String,COLUMN_NAME"
+            + " String,COLUMN_TYPE short,DATA_TYPE int,TYPE_NAME String,PRECISION int,LENGTH"
+            + " int,SCALE short,RADIX short,NULLABLE short,REMARKS String,CHAR_OCTET_LENGTH"
+            + " int,ORDINAL_POSITION int,IS_NULLABLE String,SPECIFIC_NAME String");
+  }
+
+  @Test
+  public void getColumnPrivilegesBasic() throws SQLException {
+    Assumptions.assumeFalse(isXpand());
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> sharedConn.getMetaData().getColumnPrivileges(null, null, null, null),
+        "'table' parameter must not be null");
+    testResultSetColumns(
+        sharedConn.getMetaData().getColumnPrivileges(null, null, "", null),
+        "TABLE_CAT String,TABLE_SCHEM String,TABLE_NAME String,COLUMN_NAME String,"
+            + "GRANTOR String,GRANTEE String,PRIVILEGE String,IS_GRANTABLE String");
+  }
+
+  @Test
+  public void getTablePrivilegesBasic() throws SQLException {
+    testResultSetColumns(
+        sharedConn.getMetaData().getTablePrivileges(null, null, null),
+        "TABLE_CAT String,TABLE_SCHEM String,TABLE_NAME String,GRANTOR String,"
+            + "GRANTEE String,PRIVILEGE String,IS_GRANTABLE String");
+  }
+
+  @Test
+  public void getVersionColumnsBasic() throws SQLException {
+    testResultSetColumns(
+        sharedConn.getMetaData().getVersionColumns(null, null, null),
+        "SCOPE short, COLUMN_NAME String,DATA_TYPE int,TYPE_NAME String,"
+            + "COLUMN_SIZE int,BUFFER_LENGTH int,DECIMAL_DIGITS short,"
+            + "PSEUDO_COLUMN short");
+  }
+
+  @Test
+  public void getPrimaryKeysBasic() throws SQLException {
+    testResultSetColumns(
+        sharedConn.getMetaData().getPrimaryKeys(null, null, null),
+        "TABLE_CAT String,TABLE_SCHEM String,TABLE_NAME String,COLUMN_NAME String,KEY_SEQ"
+            + " short,PK_NAME String");
+  }
+
+  @Test
+  public void getImportedKeysBasic() throws SQLException {
+    Assumptions.assumeFalse(isXpand());
+    testResultSetColumns(
+        sharedConn.getMetaData().getImportedKeys(null, null, ""),
+        "PKTABLE_CAT String,PKTABLE_SCHEM String,PKTABLE_NAME String, PKCOLUMN_NAME"
+            + " String,FKTABLE_CAT String,FKTABLE_SCHEM String,FKTABLE_NAME String,FKCOLUMN_NAME"
+            + " String,KEY_SEQ short,UPDATE_RULE short,DELETE_RULE short,FK_NAME String,PK_NAME"
+            + " String,DEFERRABILITY short");
+  }
+
+  @Test
+  public void getExportedKeysBasic() throws SQLException {
+    Assumptions.assumeFalse(isXpand());
+    testResultSetColumns(
+        sharedConn.getMetaData().getExportedKeys(null, null, ""),
+        "PKTABLE_CAT String,PKTABLE_SCHEM String,PKTABLE_NAME String, PKCOLUMN_NAME"
+            + " String,FKTABLE_CAT String,FKTABLE_SCHEM String,FKTABLE_NAME String,FKCOLUMN_NAME"
+            + " String,KEY_SEQ short,UPDATE_RULE short, DELETE_RULE short,FK_NAME String,PK_NAME"
+            + " String,DEFERRABILITY short");
+  }
+
+  @Test
+  public void getCrossReferenceBasic() throws SQLException {
+    Assumptions.assumeFalse(isXpand());
+    testResultSetColumns(
+        sharedConn.getMetaData().getCrossReference(null, null, "", null, null, ""),
+        "PKTABLE_CAT String,PKTABLE_SCHEM String,PKTABLE_NAME String, PKCOLUMN_NAME"
+            + " String,FKTABLE_CAT String,FKTABLE_SCHEM String,FKTABLE_NAME String,FKCOLUMN_NAME"
+            + " String,KEY_SEQ short,UPDATE_RULE short,DELETE_RULE short,FK_NAME String,PK_NAME"
+            + " String,DEFERRABILITY short");
+  }
+
+  @Test
+  public void getCrossReferenceResults() throws SQLException {
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getCrossReference(null, null, "cross%", null, null, "cross%");
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertEquals(null, rs.getString(2));
+    assertEquals("cross1", rs.getString(3));
+    assertEquals("id", rs.getString(4));
+    assertEquals(sharedConn.getCatalog(), rs.getString(5));
+    assertEquals(null, rs.getString(6));
+    assertEquals("cross2", rs.getString(7));
+    assertEquals("id_ref0", rs.getString(8));
+    assertTrue(rs.getInt(9) == 1 || rs.wasNull());
+    if (!isMariaDBServer() && minVersion(8, 0, 0)) {
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("DELETE_RULE"));
+    } else {
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE"));
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+    }
+    assertEquals("cross2_ibfk_1", rs.getString(12));
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertEquals(null, rs.getString(2));
+    assertEquals("cross2", rs.getString(3));
+    assertEquals("id", rs.getString(4));
+    assertEquals(sharedConn.getCatalog(), rs.getString(5));
+    assertEquals(null, rs.getString(6));
+    assertEquals("cross3", rs.getString(7));
+    assertEquals("id_ref1", rs.getString(8));
+    assertTrue(rs.getInt(9) == 1 || rs.wasNull());
+    assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt(10));
+    if (!isMariaDBServer() && minVersion(8, 0, 0)) {
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("DELETE_RULE"));
+    } else {
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+    }
+    assertTrue(
+        "fk_my_name".equals(rs.getString("FK_NAME"))
+            || "cross3_ibfk_1".equals(rs.getString("FK_NAME")));
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertEquals(null, rs.getString(2));
+    assertEquals("cross2", rs.getString(3));
+    assertEquals("id2", rs.getString(4));
+    assertEquals(sharedConn.getCatalog(), rs.getString(5));
+    assertEquals(null, rs.getString(6));
+    assertEquals("cross3", rs.getString(7));
+    assertEquals("id_ref2", rs.getString(8));
+    assertTrue(rs.getInt(9) == 2 || rs.wasNull());
+    assertEquals(DatabaseMetaData.importedKeyCascade, rs.getInt(10));
+    if (!isMariaDBServer() && minVersion(8, 0, 0)) {
+      assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getInt("DELETE_RULE"));
+    } else {
+      assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE"));
+    }
+    assertTrue("fk_my_name".equals(rs.getString(12)) || "cross3_ibfk_1".equals(rs.getString(12)));
+
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void getUdtsBasic() throws SQLException {
+    testResultSetColumns(
+        sharedConn.getMetaData().getUDTs(null, null, null, null),
+        "TYPE_CAT String,TYPE_SCHEM String,TYPE_NAME String,CLASS_NAME String,DATA_TYPE int,"
+            + "REMARKS String,BASE_TYPE short");
+  }
+
+  @Test
+  public void getSuperTypesBasic() throws SQLException {
+    testResultSetColumns(
+        sharedConn.getMetaData().getSuperTypes(null, null, null),
+        "TYPE_CAT String,TYPE_SCHEM String,TYPE_NAME String,SUPERTYPE_CAT String,"
+            + "SUPERTYPE_SCHEM String,SUPERTYPE_NAME String");
+  }
+
+  @Test
+  public void getFunctionsBasic() throws SQLException {
+    testResultSetColumns(
+        sharedConn.getMetaData().getFunctions(null, null, null),
+        "FUNCTION_CAT String, FUNCTION_SCHEM String,FUNCTION_NAME String,REMARKS"
+            + " String,FUNCTION_TYPE short, SPECIFIC_NAME String");
+  }
+
+  @Test
+  public void getSuperTablesBasic() throws SQLException {
+    testResultSetColumns(
+        sharedConn.getMetaData().getSuperTables(null, null, null),
+        "TABLE_CAT String,TABLE_SCHEM String,TABLE_NAME String, SUPERTABLE_NAME String");
+  }
+
+  @Test
+  public void testGetSchemas2() throws SQLException {
+    DatabaseMetaData dbmd = sharedConn.getMetaData();
+    ResultSet rs = dbmd.getCatalogs();
+    boolean foundTestUnitsJdbc = false;
+    while (rs.next()) {
+      if (rs.getString(1).equals(sharedConn.getCatalog())) {
+        foundTestUnitsJdbc = true;
+      }
+    }
+    assertEquals(true, foundTestUnitsJdbc);
+  }
+
+  @Test
+  public void testGetTypeInfoBasic() throws SQLException {
+    ResultSet rs = sharedConn.getMetaData().getTypeInfo();
+    while (rs.next()) {
+      rs.getInt(2);
+    }
+    ResultSetMetaData rmeta = rs.getMetaData();
+    assertTrue(rmeta.isSigned(1));
+
+    testResultSetColumns(
+        rs,
+        "TYPE_NAME String,DATA_TYPE int,PRECISION int,LITERAL_PREFIX String,LITERAL_SUFFIX"
+            + " String,CREATE_PARAMS String, NULLABLE short,CASE_SENSITIVE boolean,SEARCHABLE"
+            + " short,UNSIGNED_ATTRIBUTE boolean,FIXED_PREC_SCALE boolean, AUTO_INCREMENT boolean,"
+            + " LOCAL_TYPE_NAME String,MINIMUM_SCALE short,MAXIMUM_SCALE short,SQL_DATA_TYPE"
+            + " int,SQL_DATETIME_SUB int, NUM_PREC_RADIX int");
+  }
+
+  @Test
+  public void getColumnsTest() throws SQLException {
+    // https://jira.mariadb.org/browse/XPT-280
+    Assumptions.assumeTrue(!isXpand());
+
+    DatabaseMetaData dmd = sharedConn.getMetaData();
+    ResultSet rs = dmd.getColumns(sharedConn.getCatalog(), null, "manycols", null);
+    while (rs.next()) {
+      String columnName = rs.getString("column_name");
+      int type = rs.getInt("data_type");
+      String typeName = rs.getString("type_name");
+      assertFalse(typeName.contains("("));
+      for (char c : typeName.toCharArray()) {
+        assertTrue(c == ' ' || Character.isUpperCase(c), "bad typename " + typeName);
+      }
+      checkType(columnName, type, "tiny", Types.TINYINT);
+      checkType(columnName, type, "tiny_uns", Types.TINYINT);
+      checkType(columnName, type, "small", Types.SMALLINT);
+      checkType(columnName, type, "small_uns", Types.SMALLINT);
+      checkType(columnName, type, "medium", Types.INTEGER);
+      checkType(columnName, type, "medium_uns", Types.INTEGER);
+      checkType(columnName, type, "int_col", Types.INTEGER);
+      checkType(columnName, type, "int_col_uns", Types.INTEGER);
+      checkType(columnName, type, "big", Types.BIGINT);
+      checkType(columnName, type, "big_uns", Types.BIGINT);
+      checkType(columnName, type, "decimal_col", Types.DECIMAL);
+      checkType(columnName, type, "fcol", Types.REAL);
+      checkType(columnName, type, "fcol_uns", Types.REAL);
+      checkType(columnName, type, "dcol", Types.DOUBLE);
+      checkType(columnName, type, "dcol_uns", Types.DOUBLE);
+      checkType(columnName, type, "date_col", Types.DATE);
+      checkType(columnName, type, "time_col", Types.TIME);
+      checkType(columnName, type, "timestamp_col", Types.TIMESTAMP);
+      checkType(columnName, type, "year_col", Types.DATE);
+      checkType(columnName, type, "bit_col", Types.BIT);
+      checkType(columnName, type, "char_col", Types.CHAR);
+      checkType(columnName, type, "varchar_col", Types.VARCHAR);
+      checkType(columnName, type, "binary_col", Types.BINARY);
+      checkType(columnName, type, "tinyblob_col", Types.VARBINARY);
+      checkType(columnName, type, "blob_col", Types.LONGVARBINARY);
+      checkType(columnName, type, "longblob_col", Types.LONGVARBINARY);
+      checkType(columnName, type, "mediumblob_col", Types.LONGVARBINARY);
+      checkType(columnName, type, "tinytext_col", Types.VARCHAR);
+      checkType(columnName, type, "text_col", Types.LONGVARCHAR);
+      checkType(columnName, type, "mediumtext_col", Types.LONGVARCHAR);
+      checkType(columnName, type, "longtext_col", Types.LONGVARCHAR);
+    }
+  }
+
+  @Test
+  public void yearIsShortType() throws Exception {
+    try (java.sql.Connection connection = createCon("&yearIsDateType=false")) {
+      connection.createStatement().execute("insert into ytab values(72)");
+
+      ResultSet rs2 =
+          connection.getMetaData().getColumns(connection.getCatalog(), null, "ytab", null);
+      assertTrue(rs2.next());
+      assertEquals(Types.SMALLINT, rs2.getInt("DATA_TYPE"));
+
+      try (ResultSet rs =
+          connection.getMetaData().getColumns(connection.getCatalog(), null, "ytab", null)) {
+        assertTrue(rs.next());
+        assertEquals(Types.SMALLINT, rs.getInt("DATA_TYPE"));
+      }
+
+      try (ResultSet rs1 = connection.createStatement().executeQuery("select * from ytab")) {
+        assertEquals(rs1.getMetaData().getColumnType(1), Types.SMALLINT);
+        assertTrue(rs1.next());
+        assertTrue(rs1.getObject(1) instanceof Short);
+        assertEquals(rs1.getShort(1), 1972);
+      }
+    }
+  }
+
+  @Test
+  public void yearIsDateType() throws Exception {
+    try (Connection connection = createCon("&yearIsDateType=true")) {
+      connection.createStatement().execute("insert into ytab values(72)");
+
+      ResultSet rs2 =
+          connection.getMetaData().getColumns(connection.getCatalog(), null, "ytab", null);
+      assertTrue(rs2.next());
+      assertEquals(Types.DATE, rs2.getInt("DATA_TYPE"));
+
+      try (ResultSet rs =
+          connection.getMetaData().getColumns(connection.getCatalog(), null, "ytab", null)) {
+        assertTrue(rs.next());
+        assertEquals(Types.DATE, rs.getInt("DATA_TYPE"));
+      }
+
+      try (ResultSet rs1 = connection.createStatement().executeQuery("select * from ytab")) {
+        assertEquals(Types.DATE, rs1.getMetaData().getColumnType(1));
+        assertTrue(rs1.next());
+        assertTrue(rs1.getObject(1) instanceof Date);
+        assertEquals("1972-01-01", rs1.getDate(1).toString());
+      }
+    }
+  }
+
+  /* CONJ-15 */
+  @Test
+  public void maxCharLengthUtf8() throws Exception {
+    DatabaseMetaData dmd = sharedConn.getMetaData();
+    ResultSet rs = dmd.getColumns(sharedConn.getCatalog(), null, "maxcharlength", null);
+    assertTrue(rs.next());
+    assertEquals(rs.getInt("COLUMN_SIZE"), 1);
+  }
+
+  @Test
+  public void getPrecision() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE IF NOT EXISTS getPrecision("
+            + "num1 NUMERIC(9,4), "
+            + "num2 NUMERIC (9,0),"
+            + "num3 NUMERIC (9,4) UNSIGNED,"
+            + "num4 NUMERIC (9,0) UNSIGNED,"
+            + "num5 FLOAT(9,4),"
+            + "num6 FLOAT(9,4) UNSIGNED,"
+            + "num7 DOUBLE(9,4),"
+            + "num8 DOUBLE(9,4) UNSIGNED)");
+    ResultSet rs = stmt.executeQuery("SELECT * FROM getPrecision");
+    ResultSetMetaData rsmd = rs.getMetaData();
+    assertEquals(9, rsmd.getPrecision(1));
+    assertEquals(4, rsmd.getScale(1));
+    assertEquals(9, rsmd.getPrecision(2));
+    assertEquals(0, rsmd.getScale(2));
+    assertEquals(9, rsmd.getPrecision(3));
+    assertEquals(4, rsmd.getScale(3));
+    assertEquals(9, rsmd.getPrecision(4));
+    assertEquals(0, rsmd.getScale(4));
+    assertEquals(9, rsmd.getPrecision(5));
+    assertEquals(4, rsmd.getScale(5));
+    assertEquals(9, rsmd.getPrecision(6));
+    assertEquals(4, rsmd.getScale(6));
+    assertEquals(9, rsmd.getPrecision(7));
+    assertEquals(4, rsmd.getScale(7));
+    assertEquals(9, rsmd.getPrecision(8));
+    assertEquals(4, rsmd.getScale(8));
+  }
+
+  @Test
+  public void getTimePrecision() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM getTimePrecision");
+    ResultSetMetaData rsmd = rs.getMetaData();
+    // date
+    assertEquals(10, rsmd.getPrecision(1));
+    assertEquals(0, rsmd.getScale(1));
+    // datetime(0)
+    assertEquals(19, rsmd.getPrecision(2));
+    assertEquals(0, rsmd.getScale(2));
+    // datetime(6)
+    assertEquals(26, rsmd.getPrecision(3));
+    if (!isXpand()) assertEquals(6, rsmd.getScale(3));
+    // timestamp(0)
+    assertEquals(19, rsmd.getPrecision(4));
+    assertEquals(0, rsmd.getScale(4));
+    // timestamp(6)
+    assertEquals(26, rsmd.getPrecision(5));
+    if (!isXpand()) assertEquals(6, rsmd.getScale(5));
+    // time(0)
+    assertEquals(10, rsmd.getPrecision(6));
+    assertEquals(0, rsmd.getScale(6));
+    // time(6)
+    assertEquals(17, rsmd.getPrecision(7));
+    if (!isXpand()) assertEquals(6, rsmd.getScale(7));
+  }
+
+  @Test
+  public void metaTimeResultSet() throws SQLException {
+    final int columnSizeField = 7;
+
+    DatabaseMetaData dmd = sharedConn.getMetaData();
+    ResultSet rs = dmd.getColumns(null, null, "getTimePrecision", null);
+    // date
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(columnSizeField));
+    // datetime(0)
+    assertTrue(rs.next());
+    assertEquals(19, rs.getInt(columnSizeField));
+    // datetime(6)
+    assertTrue(rs.next());
+    if (!isXpand()) assertEquals(26, rs.getInt(columnSizeField));
+    // timestamp(0)
+    assertTrue(rs.next());
+    assertEquals(19, rs.getInt(columnSizeField));
+    // timestamp(6)
+    assertTrue(rs.next());
+    if (!isXpand()) assertEquals(26, rs.getInt(columnSizeField));
+    // time(0)
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(columnSizeField));
+    // time(6)
+    assertTrue(rs.next());
+    if (!isXpand()) assertEquals(17, rs.getInt(columnSizeField));
+
+    assertFalse(rs.next());
+  }
+
+  /**
+   * CONJ-401 - getProcedureColumns precision when server doesn't support precision.
+   *
+   * @throws SQLException if connection error occur
+   */
+  @Test
+  public void metaTimeNoPrecisionProcedureResultSet() throws SQLException {
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE PROCEDURE getProcTimePrecision2(IN  I date, "
+            + "IN t1 DATETIME,"
+            + "IN t3 timestamp,"
+            + "IN t5 time) BEGIN SELECT I; END");
+
+    final int precisionField = 8;
+    final int lengthField = 9;
+    final int scaleField = 10;
+
+    DatabaseMetaData dmd = sharedConn.getMetaData();
+    ResultSet rs = dmd.getProcedureColumns(null, null, "getProcTimePrecision2", null);
+    // date
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(precisionField));
+    assertEquals(10, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+    assertTrue(rs.wasNull());
+    // datetime(0)
+    assertTrue(rs.next());
+    assertEquals(19, rs.getInt(precisionField));
+    assertEquals(19, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+    // timestamp(0)
+    assertTrue(rs.next());
+    assertEquals(19, rs.getInt(precisionField));
+    assertEquals(19, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+    // time(0)
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(precisionField));
+    assertEquals(10, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+
+    assertFalse(rs.next());
+  }
+
+  /**
+   * CONJ-381 - getProcedureColumns returns NULL as TIMESTAMP/DATETIME precision instead of 19.
+   *
+   * @throws SQLException if connection error occur
+   */
+  @Test
+  public void metaTimeProcedureResultSet() throws SQLException {
+    Assumptions.assumeTrue(!isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE PROCEDURE getProcTimePrecision"
+            + "(IN  I date, "
+            + "IN t1 DATETIME(0),"
+            + "IN t2 DATETIME(6),"
+            + "IN t3 timestamp(0),"
+            + "IN t4 timestamp(6),"
+            + "IN t5 time ,"
+            + "IN t6 time(6)) BEGIN SELECT I; END");
+
+    final int precisionField = 8;
+    final int lengthField = 9;
+    final int scaleField = 10;
+
+    DatabaseMetaData dmd = sharedConn.getMetaData();
+    ResultSet rs = dmd.getProcedureColumns(null, null, "getProcTimePrecision", null);
+    // date
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(precisionField));
+    assertEquals(10, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+    assertTrue(rs.wasNull());
+    // datetime(0)
+    assertTrue(rs.next());
+    assertEquals(19, rs.getInt(precisionField));
+    assertEquals(19, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+    // datetime(6)
+    assertTrue(rs.next());
+    assertEquals(26, rs.getInt(precisionField));
+    assertEquals(26, rs.getInt(lengthField));
+    assertEquals(6, rs.getInt(scaleField));
+    // timestamp(0)
+    assertTrue(rs.next());
+    assertEquals(19, rs.getInt(precisionField));
+    assertEquals(19, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+    // timestamp(6)
+    assertTrue(rs.next());
+    assertEquals(26, rs.getInt(precisionField));
+    assertEquals(26, rs.getInt(lengthField));
+    assertEquals(6, rs.getInt(scaleField));
+    // time(0)
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(precisionField));
+    assertEquals(10, rs.getInt(lengthField));
+    assertEquals(0, rs.getInt(scaleField));
+    // time(6)
+    assertTrue(rs.next());
+    assertEquals(17, rs.getInt(precisionField));
+    assertEquals(17, rs.getInt(lengthField));
+    assertEquals(6, rs.getInt(scaleField));
+
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void various() {
+    org.mariadb.jdbc.DatabaseMetaData meta = sharedConn.getMetaData();
+    assertEquals(64, meta.getMaxProcedureNameLength());
+  }
+
+  @Test
+  public void getIndexInfo() throws SQLException {
+    DatabaseMetaData meta = sharedConn.getMetaData();
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> meta.getIndexInfo(null, null, null, true, true),
+        "'table' parameter must not be null");
+
+    ResultSet rs = meta.getIndexInfo(null, null, "get_index_info", false, true);
+    rs.next();
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertNull(rs.getString(2));
+    assertEquals("get_index_info", rs.getString(3));
+    assertFalse(rs.getBoolean(4));
+    assertEquals(sharedConn.getCatalog(), rs.getString(5));
+    assertEquals("PRIMARY", rs.getString(6));
+    assertEquals(DatabaseMetaData.tableIndexOther, rs.getShort(7));
+    assertEquals(1, rs.getShort(8));
+    assertEquals("no", rs.getString(9));
+    assertEquals("A", rs.getString(10));
+    assertEquals(0L, rs.getLong(11));
+    assertNull(rs.getString(12));
+    assertNull(rs.getString(13));
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertNull(rs.getString(2));
+    assertEquals("get_index_info", rs.getString(3));
+    assertTrue(rs.getBoolean(4));
+    assertEquals(sharedConn.getCatalog(), rs.getString(5));
+    assertEquals("ind_cust", rs.getString(6));
+    assertEquals(DatabaseMetaData.tableIndexOther, rs.getShort(7));
+    assertEquals(1, rs.getShort(8));
+    assertEquals("customer_id", rs.getString(9));
+    assertEquals("A", rs.getString(10));
+    assertEquals(0L, rs.getLong(11));
+    assertNull(rs.getString(12));
+    assertNull(rs.getString(13));
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertNull(rs.getString(2));
+    assertEquals("get_index_info", rs.getString(3));
+    assertTrue(rs.getBoolean(4));
+    assertEquals(sharedConn.getCatalog(), rs.getString(5));
+    assertEquals("ind_prod", rs.getString(6));
+    assertEquals(DatabaseMetaData.tableIndexOther, rs.getShort(7));
+    assertEquals(1, rs.getShort(8));
+    assertEquals("product_category", rs.getString(9));
+    assertEquals("A", rs.getString(10));
+    assertEquals(0L, rs.getLong(11));
+    assertNull(rs.getString(12));
+    assertNull(rs.getString(13));
+
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertNull(rs.getString(2));
+    assertEquals("get_index_info", rs.getString(3));
+    assertTrue(rs.getBoolean(4));
+    assertEquals(sharedConn.getCatalog(), rs.getString(5));
+    assertEquals("ind_prod", rs.getString(6));
+    assertEquals(DatabaseMetaData.tableIndexOther, rs.getShort(7));
+    assertEquals(2, rs.getShort(8));
+    assertEquals("product_id", rs.getString(9));
+    assertEquals("A", rs.getString(10));
+    assertEquals(0L, rs.getLong(11));
+    assertNull(rs.getString(12));
+    assertNull(rs.getString(13));
+  }
+
+  @Test
+  public void getPseudoColumns() throws SQLException {
+    DatabaseMetaData meta = sharedConn.getMetaData();
+    ResultSet rs = meta.getPseudoColumns(null, null, null, null);
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void constantTest() throws SQLException {
+    DatabaseMetaData meta = sharedConn.getMetaData();
+    assertFalse(meta.othersUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY));
+    assertFalse(meta.othersDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY));
+    assertFalse(meta.othersInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY));
+    assertFalse(meta.updatesAreDetected(ResultSet.TYPE_FORWARD_ONLY));
+    assertFalse(meta.deletesAreDetected(ResultSet.TYPE_FORWARD_ONLY));
+    assertFalse(meta.insertsAreDetected(ResultSet.TYPE_FORWARD_ONLY));
+    assertTrue(meta.supportsBatchUpdates());
+    assertEquals(sharedConn, sharedConn.getMetaData().getConnection());
+    assertTrue(meta.supportsSavepoints());
+    assertFalse(meta.supportsNamedParameters());
+    assertFalse(meta.supportsMultipleOpenResults());
+    assertTrue(meta.supportsGetGeneratedKeys());
+    assertTrue(meta.supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT));
+    assertFalse(meta.supportsResultSetHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT));
+    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, meta.getResultSetHoldability());
+    assertTrue(meta.getDatabaseMajorVersion() >= 5);
+    assertTrue(meta.getDatabaseMinorVersion() >= 0);
+    assertEquals(4, meta.getJDBCMajorVersion());
+    assertEquals(2, meta.getJDBCMinorVersion());
+    assertEquals(DatabaseMetaData.sqlStateSQL99, meta.getSQLStateType());
+    assertFalse(meta.locatorsUpdateCopy());
+    assertFalse(meta.supportsStatementPooling());
+    assertEquals(RowIdLifetime.ROWID_UNSUPPORTED, meta.getRowIdLifetime());
+    assertTrue(meta.supportsStoredFunctionsUsingCallSyntax());
+    assertFalse(meta.autoCommitFailureClosesAllResultSets());
+
+    meta.unwrap(java.sql.DatabaseMetaData.class);
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> meta.unwrap(String.class),
+        "The receiver is not a wrapper for java.lang.String");
+
+    assertEquals(4294967295L, meta.getMaxLogicalLobSize());
+    assertFalse(meta.supportsRefCursors());
+    assertTrue(meta.supportsGetGeneratedKeys());
+    assertTrue(meta.generatedKeyAlwaysReturned());
+    assertTrue(meta.allProceduresAreCallable());
+    assertTrue(meta.allTablesAreSelectable());
+    assertNotNull(meta.getURL());
+    assertNotNull(meta.getUserName());
+    assertFalse(meta.isReadOnly());
+    assertFalse(meta.nullsAreSortedHigh());
+    assertTrue(meta.nullsAreSortedLow());
+    assertFalse(meta.nullsAreSortedAtStart());
+    assertTrue(meta.nullsAreSortedAtEnd());
+    assertEquals(isMariaDBServer() ? "MariaDB" : "MySQL", meta.getDatabaseProductName());
+    assertEquals("MariaDB Connector/J", meta.getDriverName());
+    assertTrue(meta.getDriverVersion().startsWith("3."));
+    assertTrue(meta.getDriverMajorVersion() >= 0);
+    assertTrue(meta.getDriverMinorVersion() >= 0);
+    assertFalse(meta.usesLocalFiles());
+    assertFalse(meta.usesLocalFilePerTable());
+    assertEquals(meta.supportsMixedCaseIdentifiers(), meta.supportsMixedCaseQuotedIdentifiers());
+    assertEquals(meta.storesUpperCaseIdentifiers(), meta.storesUpperCaseQuotedIdentifiers());
+    assertEquals(meta.storesLowerCaseIdentifiers(), meta.storesLowerCaseQuotedIdentifiers());
+    assertEquals(meta.storesMixedCaseIdentifiers(), meta.storesMixedCaseQuotedIdentifiers());
+    assertEquals("`", meta.getIdentifierQuoteString());
+    assertNotNull(meta.getSQLKeywords());
+    assertNotNull(meta.getNumericFunctions());
+    assertNotNull(meta.getStringFunctions());
+    assertNotNull(meta.getSystemFunctions());
+    assertNotNull(meta.getTimeDateFunctions());
+    assertEquals("\\", meta.getSearchStringEscape());
+    assertEquals("#@", meta.getExtraNameCharacters());
+    assertTrue(meta.supportsAlterTableWithAddColumn());
+    assertTrue(meta.supportsAlterTableWithDropColumn());
+    assertTrue(meta.supportsColumnAliasing());
+    assertTrue(meta.nullPlusNonNullIsNull());
+    assertTrue(meta.supportsConvert());
+    assertTrue(meta.supportsAlterTableWithAddColumn());
+    assertTrue(meta.supportsConvert(Types.INTEGER, Types.REAL));
+    assertFalse(meta.supportsConvert(Types.INTEGER, Types.BLOB));
+    assertTrue(meta.supportsConvert(Types.BLOB, Types.TINYINT));
+    assertFalse(meta.supportsConvert(Types.BLOB, Types.ARRAY));
+    assertTrue(meta.supportsConvert(Types.CLOB, Types.NUMERIC));
+    assertFalse(meta.supportsConvert(Types.CLOB, Types.ARRAY));
+    assertTrue(meta.supportsConvert(Types.DATE, Types.VARCHAR));
+    assertFalse(meta.supportsConvert(Types.DATE, Types.ARRAY));
+    assertTrue(meta.supportsConvert(Types.TIME, Types.VARCHAR));
+    assertFalse(meta.supportsConvert(Types.TIME, Types.ARRAY));
+    assertTrue(meta.supportsConvert(Types.TIMESTAMP, Types.VARCHAR));
+    assertFalse(meta.supportsConvert(Types.TIMESTAMP, Types.ARRAY));
+    assertFalse(meta.supportsConvert(Types.ARRAY, Types.TIMESTAMP));
+    assertTrue(meta.supportsTableCorrelationNames());
+    assertTrue(meta.supportsDifferentTableCorrelationNames());
+    assertTrue(meta.supportsExpressionsInOrderBy());
+    assertTrue(meta.supportsOrderByUnrelated());
+    assertTrue(meta.supportsGroupBy());
+    assertTrue(meta.supportsGroupByUnrelated());
+    assertTrue(meta.supportsGroupByBeyondSelect());
+    assertTrue(meta.supportsLikeEscapeClause());
+    assertTrue(meta.supportsMultipleResultSets());
+    assertTrue(meta.supportsMultipleTransactions());
+    assertTrue(meta.supportsNonNullableColumns());
+    assertTrue(meta.supportsMinimumSQLGrammar());
+    assertTrue(meta.supportsCoreSQLGrammar());
+    assertTrue(meta.supportsExtendedSQLGrammar());
+    assertTrue(meta.supportsANSI92EntryLevelSQL());
+    assertTrue(meta.supportsANSI92IntermediateSQL());
+    assertTrue(meta.supportsANSI92FullSQL());
+    assertTrue(meta.supportsIntegrityEnhancementFacility());
+    assertTrue(meta.supportsOuterJoins());
+    assertTrue(meta.supportsFullOuterJoins());
+    assertTrue(meta.supportsLimitedOuterJoins());
+    assertEquals("schema", meta.getSchemaTerm());
+    assertEquals("procedure", meta.getProcedureTerm());
+    assertEquals("database", meta.getCatalogTerm());
+    assertTrue(meta.isCatalogAtStart());
+    assertEquals(".", meta.getCatalogSeparator());
+    assertFalse(meta.supportsSchemasInDataManipulation());
+    assertFalse(meta.supportsSchemasInProcedureCalls());
+    assertFalse(meta.supportsSchemasInTableDefinitions());
+    assertFalse(meta.supportsSchemasInIndexDefinitions());
+    assertFalse(meta.supportsSchemasInPrivilegeDefinitions());
+    assertTrue(meta.supportsCatalogsInDataManipulation());
+    assertTrue(meta.supportsCatalogsInProcedureCalls());
+    assertTrue(meta.supportsCatalogsInTableDefinitions());
+    assertTrue(meta.supportsCatalogsInIndexDefinitions());
+    assertTrue(meta.supportsCatalogsInPrivilegeDefinitions());
+    assertFalse(meta.supportsPositionedDelete());
+    assertFalse(meta.supportsPositionedUpdate());
+    assertTrue(meta.supportsSelectForUpdate());
+    assertTrue(meta.supportsStoredProcedures());
+    assertTrue(meta.supportsSubqueriesInComparisons());
+    assertTrue(meta.supportsSubqueriesInExists());
+    assertTrue(meta.supportsSubqueriesInIns());
+    assertTrue(meta.supportsSubqueriesInComparisons());
+    assertTrue(meta.supportsSubqueriesInQuantifieds());
+    assertTrue(meta.supportsCorrelatedSubqueries());
+    assertTrue(meta.supportsUnion());
+    assertTrue(meta.supportsUnionAll());
+    assertTrue(meta.supportsOpenCursorsAcrossCommit());
+    assertTrue(meta.supportsOpenCursorsAcrossRollback());
+    assertTrue(meta.supportsOpenStatementsAcrossCommit());
+    assertTrue(meta.supportsOpenStatementsAcrossRollback());
+    assertEquals(Integer.MAX_VALUE, meta.getMaxBinaryLiteralLength());
+    assertEquals(Integer.MAX_VALUE, meta.getMaxCharLiteralLength());
+    assertEquals(64, meta.getMaxColumnNameLength());
+    assertEquals(64, meta.getMaxColumnsInGroupBy());
+    assertEquals(16, meta.getMaxColumnsInIndex());
+    assertEquals(64, meta.getMaxColumnsInOrderBy());
+    assertEquals(Short.MAX_VALUE, meta.getMaxColumnsInSelect());
+    assertEquals(0, meta.getMaxColumnsInTable());
+    assertEquals(0, meta.getMaxConnections());
+    assertEquals(0, meta.getMaxCursorNameLength());
+    assertEquals(256, meta.getMaxIndexLength());
+    assertEquals(0, meta.getMaxSchemaNameLength());
+    assertEquals(64, meta.getMaxProcedureNameLength());
+    assertEquals(0, meta.getMaxCatalogNameLength());
+    assertEquals(0, meta.getMaxRowSize());
+    assertFalse(meta.doesMaxRowSizeIncludeBlobs());
+    assertEquals(0, meta.getMaxStatementLength());
+    assertEquals(0, meta.getMaxStatements());
+    assertEquals(64, meta.getMaxTableNameLength());
+    assertEquals(256, meta.getMaxTablesInSelect());
+    assertEquals(0, meta.getMaxUserNameLength());
+    assertEquals(Connection.TRANSACTION_REPEATABLE_READ, meta.getDefaultTransactionIsolation());
+    assertTrue(meta.supportsTransactions());
+    assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED));
+    assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED));
+    assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ));
+    assertTrue(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE));
+    assertFalse(meta.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE));
+    assertTrue(meta.supportsDataDefinitionAndDataManipulationTransactions());
+    assertFalse(meta.supportsDataManipulationTransactionsOnly());
+    assertTrue(meta.dataDefinitionCausesTransactionCommit());
+    assertFalse(meta.dataDefinitionIgnoredInTransactions());
+  }
+
+  @Test
+  public void testMetaCatalog() throws Exception {
+    DatabaseMetaData meta = sharedConn.getMetaData();
+    ResultSet rs = meta.getProcedures(sharedConn.getCatalog(), null, "testMetaCatalog");
+    assertTrue(rs.next());
+    assertEquals(sharedConn.getCatalog(), rs.getString(1));
+    assertNull(rs.getString(2));
+    assertEquals("testMetaCatalog", rs.getString(3));
+    assertNull(rs.getString(4));
+    assertNull(rs.getString(5));
+    assertNull(rs.getString(6));
+    assertEquals("comments", rs.getString(7));
+    assertEquals(DatabaseMetaData.procedureNoResult, rs.getInt(8));
+    assertEquals("testMetaCatalog", rs.getString(9));
+    assertFalse(rs.next());
+
+    // test with bad catalog
+    rs = meta.getProcedures("yahoooo", null, "testMetaCatalog");
+    assertFalse(rs.next());
+
+    // test without catalog
+    rs = meta.getProcedures(null, null, "testMetaCatalog");
+    assertTrue(rs.next());
+    assertTrue("testMetaCatalog".equals(rs.getString(3)));
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = sharedConn.createStatement().executeQuery("SELECT * FROM json_test");
+    ResultSetMetaData meta = rs.getMetaData();
+    assertTrue(
+        "LONGTEXT".equals(meta.getColumnTypeName(1)) || "JSON".equals(meta.getColumnTypeName(1)));
+    assertEquals(Types.LONGVARCHAR, meta.getColumnType(1));
+    assertEquals("java.lang.String", meta.getColumnClassName(1));
+  }
+
+  @Test
+  public void getTypeMetaData() throws SQLException {
+    //            "create table text_types_text (varchar100           varchar(100),\n" +
+    //                    "  varchar255           varchar(255),\n" +
+    //                    "  text                 text,\n" +
+    //                    "  `tinytext`           tinytext,\n" +
+    //                    "  `mediumtext`         mediumtext,\n" +
+    //                    "  `longtext`           longtext)"
+    try (ResultSet resultSet =
+        sharedConn.createStatement().executeQuery("select * from text_types_text")) {
+      ResultSetMetaData metaData = resultSet.getMetaData();
+
+      String[] expected =
+          new String[] {
+            "varchar100 12 VARCHAR 100",
+            "varchar255 12 VARCHAR 255",
+            "text 12 TEXT 65535",
+            "tinytext 12 VARCHAR 255",
+            "mediumtext 12 MEDIUMTEXT 16777215",
+            "longtext -1 LONGTEXT 0"
+          };
+      for (int i = 0; i < expected.length; i++) {
+        assertEquals(
+            expected[i],
+            metaData.getColumnName(i + 1)
+                + " "
+                + metaData.getColumnType(i + 1)
+                + " "
+                + metaData.getColumnTypeName(i + 1)
+                + " "
+                + metaData.getPrecision(i + 1));
+      }
+    }
+  }
+
+  @Test
+  public void foreignKeyTest() throws SQLException {
+
+    try (Connection con = createCon()) {
+      String db = con.getCatalog();
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("DROP DATABASE IF EXISTS dbTmp");
+      stmt.execute("DROP TABLE IF EXISTS tableWithForeignKey");
+      stmt.execute("DROP TABLE IF EXISTS tableWithPk");
+      stmt.execute("CREATE TABLE tableWithPk(id BIGINT PRIMARY KEY) ENGINE=InnoDB");
+
+      stmt.execute(
+          "CREATE TABLE IF NOT EXISTS tableWithForeignKey\n"
+              + "          (\n"
+              + "                  id BIGINT NOT NULL AUTO_INCREMENT,\n"
+              + "                  fk_id BIGINT,\n"
+              + "                  PRIMARY KEY (id),\n"
+              + "  CONSTRAINT fk_key FOREIGN KEY (fk_id) REFERENCES tableWithPk (id)\n"
+              + "          ) ENGINE=InnoDB");
+      DatabaseMetaData dbmd = con.getMetaData();
+      ResultSet rs = dbmd.getImportedKeys(null, null, "tableWithForeignKey");
+      assertTrue(rs.next());
+      rs.close();
+
+      rs = dbmd.getImportedKeys("", null, "tableWithForeignKey");
+      assertTrue(rs.next());
+
+      stmt.execute("CREATE DATABASE dbTmp");
+      con.setCatalog("dbTmp");
+      try {
+        rs = dbmd.getImportedKeys("", null, "tableWithForeignKey");
+        assertFalse(rs.next());
+
+        rs = dbmd.getImportedKeys(null, null, "tableWithForeignKey");
+        assertTrue(rs.next());
+      } finally {
+        con.setCatalog(db);
+        stmt.execute("DROP DATABASE dbTmp");
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/DriverTest.java b/src/test/java/org/mariadb/jdbc/integration/DriverTest.java
new file mode 100644
index 0000000..03d8712
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/DriverTest.java
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.Configuration;
+
+public class DriverTest extends Common {
+
+  @Test
+  public void ensureDescriptionFilled() throws Exception {
+    Properties descr = new Properties();
+    try (InputStream inputStream =
+        Common.class.getClassLoader().getResourceAsStream("driver.properties")) {
+      descr.load(inputStream);
+    }
+
+    // check that description is present
+    for (Field field : Configuration.Builder.class.getDeclaredFields()) {
+      if (!field.getName().startsWith("_")) {
+        if (descr.get(field.getName()) == null && !"$jacocoData".equals(field.getName()))
+          throw new Exception(String.format("Missing %s description", field.getName()));
+      }
+    }
+
+    // check that no description without option
+    for (Map.Entry<Object, Object> entry : descr.entrySet()) {
+      // NoSuchFieldException will be thrown if not present
+      Configuration.Builder.class.getDeclaredField(entry.getKey().toString());
+    }
+  }
+
+  @Test
+  public void getPropertyInfo() throws SQLException {
+    Driver driver = new org.mariadb.jdbc.Driver();
+    assertEquals(0, driver.getPropertyInfo(null, null).length);
+    assertEquals(0, driver.getPropertyInfo("jdbc:bla//", null).length);
+
+    Properties properties = new Properties();
+    properties.put("password", "myPwd");
+    DriverPropertyInfo[] driverPropertyInfos =
+        driver.getPropertyInfo("jdbc:mariadb://localhost/db?user=root", properties);
+    for (DriverPropertyInfo driverPropertyInfo : driverPropertyInfos) {
+      if (!"$jacocoData".equals(driverPropertyInfo.name)) {
+        assertNotNull(
+            driverPropertyInfo.description, "no description for " + driverPropertyInfo.name);
+      }
+    }
+  }
+
+  @Test
+  public void basicInfo() {
+    Driver driver = new org.mariadb.jdbc.Driver();
+    assertEquals(3, driver.getMajorVersion());
+    assertTrue(driver.getMinorVersion() > -1);
+    assertTrue(driver.jdbcCompliant());
+    assertThrows(SQLFeatureNotSupportedException.class, driver::getParentLogger);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/EofTest.java b/src/test/java/org/mariadb/jdbc/integration/EofTest.java
new file mode 100644
index 0000000..5f1069e
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/EofTest.java
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Connection;
+
+public class EofTest extends Common {
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    createSequenceTables();
+  }
+
+  @Test
+  public void basicResultset() throws Exception {
+    basicResultset(sharedConn);
+    basicResultset(sharedConnBinary);
+    try (Connection con = createCon("deprecateEof=false")) {
+      basicResultset(con);
+    }
+    try (Connection con =
+        createCon("deprecateEof=false&useServerPrepStmts=true&enableSkipMeta=false")) {
+      basicResultset(con);
+    }
+    try (Connection con =
+        createCon("deprecateEof=false&useServerPrepStmts=true&enableSkipMeta=true")) {
+      basicResultset(con);
+    }
+  }
+
+  public void basicResultset(Connection con) throws Exception {
+    try (PreparedStatement prep =
+        con.prepareStatement("SELECT * FROM sequence_1_to_10 where 1 = ?")) {
+      prep.setFetchSize(2);
+      prep.setMaxRows(4);
+      prep.setInt(1, 1);
+      ResultSet rs = prep.executeQuery();
+      rs.next();
+      assertEquals(1, rs.getInt(1));
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ErrorTest.java b/src/test/java/org/mariadb/jdbc/integration/ErrorTest.java
new file mode 100644
index 0000000..8fb519f
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ErrorTest.java
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class ErrorTest extends Common {
+
+  @BeforeAll
+  public static void begin() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE deadlock(a int primary key)");
+    stmt.execute("CREATE TABLE deadlock2(a int primary key) ENGINE=InnoDB");
+
+    stmt.execute("FLUSH TABLES");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS deadlock");
+    stmt.execute("DROP TABLE IF EXISTS deadlock2");
+  }
+
+  @Test
+  public void dumpQueryOnException() throws Exception {
+    try (Connection con = createCon("dumpQueriesOnException")) {
+      Statement stmt = con.createStatement();
+      try {
+        stmt.execute("SELECT 'long value' FROM wrongTable");
+        fail();
+      } catch (SQLException e) {
+        assertTrue(e.getMessage().contains("Query is: SELECT 'long value' FROM wrongTable"));
+      }
+    }
+
+    try (Connection con = createCon("maxQuerySizeToLog=100&dumpQueriesOnException")) {
+      Statement stmt = con.createStatement();
+      try {
+        stmt.execute("SELECT 'long value' FROM wrongTable");
+        fail();
+      } catch (SQLException e) {
+        assertTrue(e.getMessage().contains("Query is: SELECT 'long value' FROM wrongTable"));
+      }
+    }
+
+    try (Connection con = createCon("maxQuerySizeToLog=13&dumpQueriesOnException")) {
+      Statement stmt = con.createStatement();
+      try {
+        stmt.execute("SELECT 'long value' FROM wrongTable");
+        fail();
+      } catch (SQLException e) {
+        assertTrue(e.getMessage().contains("Query is: SELECT 'lo..."));
+      }
+    }
+  }
+
+  @Test
+  public void testPre41ErrorFormat() throws Exception {
+    testPre41ErrorFormat(sharedConn);
+    try (Connection con =
+        createCon("dumpQueriesOnException&includeInnodbStatusInDeadlockExceptions")) {
+      testPre41ErrorFormat(con);
+    }
+  }
+
+  private void testPre41ErrorFormat(Connection con) throws Exception {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !isXpand());
+    SQLException exception = null;
+    int max_connections;
+    Statement stmt = con.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT @@max_connections");
+    rs.next();
+    max_connections = rs.getInt(1);
+    Assumptions.assumeTrue(max_connections < 1000);
+    Connection[] cons = new Connection[max_connections];
+    for (int i = 0; i < max_connections; i++) {
+      try {
+        cons[i] = createCon();
+      } catch (SQLException sqle) {
+        exception = sqle;
+      }
+    }
+
+    for (int i = 0; i < max_connections; i++) {
+      try {
+        if (cons[i] != null) cons[i].close();
+      } catch (SQLException sqle) {
+        // eat
+      }
+    }
+    assertNotNull(exception);
+    assertTrue(exception.getMessage().contains("Too many"));
+  }
+
+  @Test
+  public void deadLockInformation() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("insert into deadlock(a) values(0), (1)");
+
+    try (Connection conn1 =
+        createCon(
+            "includeInnodbStatusInDeadlockExceptions&includeThreadDumpInDeadlockExceptions")) {
+
+      conn1.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+      Statement stmt1 = conn1.createStatement();
+      try {
+        stmt1.execute("SET SESSION idle_transaction_timeout=2");
+      } catch (SQLException e) {
+        // eat ( for mariadb >= 10.3)
+      }
+      stmt.execute("start transaction");
+      stmt.execute("update deadlock set a = 2 where a <> 0");
+      Assumptions.assumeFalse(isXpand());
+      try (Connection conn2 =
+          createCon(
+              "&includeInnodbStatusInDeadlockExceptions&includeThreadDumpInDeadlockExceptions")) {
+
+        Statement stmt2 = conn2.createStatement();
+        conn2.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+        try {
+          stmt2.execute("SET SESSION idle_transaction_timeout=2, innodb_lock_wait_timeout=2");
+        } catch (SQLException e) {
+          // eat ( for mariadb >= 10.3)
+        }
+        stmt2.execute("start transaction");
+        try {
+          stmt2.execute("update deadlock set a = 3 where a <> 1");
+          fail("Must have thrown deadlock exception");
+        } catch (SQLException sqle) {
+          assertTrue(sqle.getMessage().contains("current threads:"));
+          assertTrue(sqle.getMessage().contains("deadlock information"));
+        }
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/FailoverTest.java b/src/test/java/org/mariadb/jdbc/integration/FailoverTest.java
new file mode 100644
index 0000000..5925bfb
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/FailoverTest.java
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.sql.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.export.HaMode;
+
+public class FailoverTest extends Common {
+
+  @Test
+  public void simpleFailoverTransactionReplay() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try (Connection con = createProxyCon(HaMode.SEQUENTIAL, "")) {
+      con.setNetworkTimeout(Runnable::run, 200);
+      long threadId = con.getContext().getThreadId();
+      Statement stmt = con.createStatement();
+      proxy.restart(200);
+      assertThrowsContains(
+          SQLTransientConnectionException.class,
+          () -> stmt.execute("SELECT 1"),
+          "Driver has reconnect connection after a communications link failure");
+      ;
+      Assertions.assertTrue(con.getContext().getThreadId() != threadId);
+    }
+  }
+
+  @Test
+  public void simpleFailoverTransactionReplayNoQuery() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try (Connection con = createProxyCon(HaMode.SEQUENTIAL, "")) {
+      con.setNetworkTimeout(Runnable::run, 200);
+      long threadId = con.getContext().getThreadId();
+      Statement stmt = con.createStatement();
+      proxy.restart(200);
+
+      con.isValid(1000);
+      Assertions.assertTrue(con.getContext().getThreadId() != threadId);
+    }
+  }
+
+  @Test
+  public void transactionReplay() throws SQLException {
+    transactionReplay(true);
+    transactionReplay(false);
+  }
+
+  private void transactionReplay(boolean transactionReplay) throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    Statement st = sharedConn.createStatement();
+    st.execute("DROP TABLE IF EXISTS transaction_failover");
+    st.execute(
+        "CREATE TABLE transaction_failover "
+            + "(id int not null primary key auto_increment, test varchar(20)) "
+            + "engine=innodb");
+
+    try (Connection con =
+        createProxyCon(HaMode.SEQUENTIAL, "&transactionReplay=" + transactionReplay)) {
+      assertEquals(Connection.TRANSACTION_REPEATABLE_READ, con.getTransactionIsolation());
+      con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
+      final Statement stmt = con.createStatement();
+      con.setNetworkTimeout(Runnable::run, 200);
+      long threadId = con.getContext().getThreadId();
+
+      stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test0')");
+      con.setAutoCommit(false);
+      stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test1')");
+      stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test2')");
+      proxy.restart(300);
+      if (transactionReplay) {
+        stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test3')");
+        con.commit();
+
+        ResultSet rs = stmt.executeQuery("SELECT * FROM transaction_failover");
+        for (int i = 0; i < 4; i++) {
+          assertTrue(rs.next());
+          assertEquals("test" + i, rs.getString("test"));
+        }
+        con.commit();
+        Assertions.assertTrue(con.getContext().getThreadId() != threadId);
+        assertFalse(con.getAutoCommit());
+        assertEquals(Connection.TRANSACTION_READ_UNCOMMITTED, con.getTransactionIsolation());
+      } else {
+        Common.assertThrowsContains(
+            SQLTransientConnectionException.class,
+            () -> stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test3')"),
+            "In progress transaction was lost");
+      }
+    }
+  }
+
+  @Test
+  public void transactionReplayDuringCommit() throws SQLException {
+    transactionReplayDuringCommit(true);
+    transactionReplayDuringCommit(false);
+  }
+
+  private void transactionReplayDuringCommit(boolean transactionReplay) throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    Statement st = sharedConn.createStatement();
+    st.execute("DROP TABLE IF EXISTS transaction_failover");
+    st.execute(
+        "CREATE TABLE transaction_failover "
+            + "(id int not null primary key auto_increment, test varchar(20)) "
+            + "engine=innodb");
+
+    try (Connection con =
+        createProxyCon(HaMode.SEQUENTIAL, "&transactionReplay=" + transactionReplay)) {
+      assertEquals(Connection.TRANSACTION_REPEATABLE_READ, con.getTransactionIsolation());
+      con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
+      final Statement stmt = con.createStatement();
+      con.setNetworkTimeout(Runnable::run, 200);
+      long threadId = con.getContext().getThreadId();
+
+      stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test0')");
+      con.setAutoCommit(false);
+      stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test1')");
+      stmt.executeUpdate("INSERT INTO transaction_failover (test) VALUES ('test2')");
+      proxy.restart(300);
+      if (transactionReplay) {
+        Common.assertThrowsContains(
+            SQLTransientConnectionException.class,
+            con::commit,
+            "Driver has reconnect connection after a communications failure");
+
+        ResultSet rs = stmt.executeQuery("SELECT * FROM transaction_failover");
+        for (int i = 0; i < 1; i++) {
+          assertTrue(rs.next());
+          assertEquals("test" + i, rs.getString("test"));
+        }
+
+        Assertions.assertTrue(con.getContext().getThreadId() != threadId);
+        assertFalse(con.getAutoCommit());
+        assertEquals(Connection.TRANSACTION_READ_UNCOMMITTED, con.getTransactionIsolation());
+      } else {
+        Common.assertThrowsContains(
+            SQLTransientConnectionException.class, con::commit, "during a COMMIT statement");
+      }
+    }
+  }
+
+  @Test
+  public void transactionReplayPreparedStatement() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    transactionReplayPreparedStatement(true, true);
+    transactionReplayPreparedStatement(false, true);
+    transactionReplayPreparedStatement(true, false);
+    transactionReplayPreparedStatement(false, false);
+  }
+
+  private void transactionReplayPreparedStatement(boolean binary, boolean transactionReplay)
+      throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS transaction_failover_3");
+    stmt.execute(
+        "CREATE TABLE transaction_failover_3 "
+            + "(id int not null primary key auto_increment, test varchar(20)) "
+            + "engine=innodb");
+
+    try (Connection con =
+        createProxyCon(
+            HaMode.SEQUENTIAL,
+            "&useServerPrepStmts=" + binary + "&transactionReplay=" + transactionReplay)) {
+      stmt = con.createStatement();
+      con.setNetworkTimeout(Runnable::run, 200);
+      long threadId = con.getContext().getThreadId();
+
+      stmt.executeUpdate("INSERT INTO transaction_failover_3 (test) VALUES ('test0')");
+      con.setAutoCommit(false);
+      stmt.executeUpdate("INSERT INTO transaction_failover_3 (test) VALUES ('test1')");
+      try (PreparedStatement p =
+          con.prepareStatement("INSERT INTO transaction_failover_3 (test) VALUES (?)")) {
+        p.setString(1, "test2");
+        p.execute();
+        p.setAsciiStream(1, new ByteArrayInputStream("test3".getBytes()));
+        p.execute();
+
+        proxy.restart(300);
+        p.setString(1, "test4");
+        if (transactionReplay) {
+          p.execute();
+        } else {
+          Common.assertThrowsContains(
+              SQLTransientConnectionException.class,
+              p::execute,
+              "In progress transaction was lost");
+        }
+      }
+      if (transactionReplay) {
+        con.commit();
+        ResultSet rs = stmt.executeQuery("SELECT * FROM transaction_failover_3");
+
+        for (int i = 0; i < 5; i++) {
+          assertTrue(rs.next());
+          assertEquals("test" + i, rs.getString("test"));
+        }
+        con.commit();
+        Assertions.assertTrue(con.getContext().getThreadId() != threadId);
+        assertFalse(con.getAutoCommit());
+      }
+    }
+  }
+
+  @Test
+  public void transactionReplayPreparedStatementBatch() throws Exception {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+    for (int i = 0; i < 8; i++) {
+      transactionReplayPreparedStatementBatch((i & 1) > 0, (i & 2) > 0, (i & 4) > 0);
+    }
+  }
+
+  private void transactionReplayPreparedStatementBatch(
+      boolean text, boolean useBulk, boolean transactionReplay) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS transaction_failover_2");
+    stmt.execute(
+        "CREATE TABLE transaction_failover_2 "
+            + "(id int not null primary key auto_increment, test varchar(20)) "
+            + "engine=innodb");
+
+    try (Connection con =
+        createProxyCon(
+            HaMode.SEQUENTIAL,
+            "&useServerPrepStmts="
+                + !text
+                + "&useBulkStmts="
+                + useBulk
+                + "&transactionReplay="
+                + transactionReplay)) {
+      con.setNetworkTimeout(Runnable::run, 500);
+      long threadId = con.getContext().getThreadId();
+      execute(con, transactionReplay, threadId);
+      threadId = con.getContext().getThreadId();
+      execute(con, transactionReplay, threadId);
+    }
+  }
+
+  private void execute(Connection con, boolean transactionReplay, long threadId)
+      throws SQLException {
+    Statement stmt = con.createStatement();
+
+    stmt.executeUpdate("INSERT INTO transaction_failover_2 (test) VALUES ('test0')");
+    con.setAutoCommit(false);
+    stmt.executeUpdate("INSERT INTO transaction_failover_2 (test) VALUES ('test1')");
+    try (PreparedStatement p =
+        con.prepareStatement("INSERT INTO transaction_failover_2 (test) VALUES (?)")) {
+      p.setString(1, "test2");
+      p.execute();
+      p.setString(1, "test3");
+      p.addBatch();
+      p.setString(1, "test4");
+      p.addBatch();
+      p.executeBatch();
+
+      proxy.restart(300);
+      p.setString(1, "test5");
+      p.addBatch();
+      p.setString(1, "test6");
+      p.addBatch();
+
+      if (transactionReplay) {
+        p.executeBatch();
+        con.commit();
+
+        ResultSet rs = stmt.executeQuery("SELECT * FROM transaction_failover_2");
+        for (int i = 0; i < 6; i++) {
+          assertTrue(rs.next());
+          assertEquals("test" + i, rs.getString("test"));
+        }
+        con.commit();
+        Assertions.assertTrue(con.getContext().getThreadId() != threadId);
+        assertFalse(con.getAutoCommit());
+      } else {
+        try {
+          p.executeBatch();
+          Assertions.fail();
+        } catch (SQLException e) {
+          SQLException ee = (SQLException) ((e instanceof BatchUpdateException) ? e.getCause() : e);
+          assertEquals(ee.getMessage(), e.getMessage());
+          assertEquals(ee.getSQLState(), e.getSQLState());
+          assertEquals(ee.getErrorCode(), e.getErrorCode());
+          assertTrue(ee.getMessage().contains("In progress transaction was lost"));
+        }
+      }
+    }
+    stmt.execute("TRUNCATE transaction_failover_2");
+    stmt.executeUpdate("INSERT INTO transaction_failover_2 (test) VALUES ('test0')");
+    con.setAutoCommit(false);
+    stmt.executeUpdate("INSERT INTO transaction_failover_2 (test) VALUES ('test1')");
+    try (PreparedStatement p =
+        con.prepareStatement("INSERT INTO transaction_failover_2 (test)  VALUES (?)")) {
+
+      proxy.restart(300);
+      p.setString(1, "test2");
+      p.addBatch();
+      p.setString(1, "test3");
+      p.addBatch();
+      p.setString(1, "test4");
+      p.addBatch();
+      p.setString(1, "test5");
+      p.addBatch();
+
+      if (transactionReplay) {
+        p.executeBatch();
+        con.commit();
+
+        ResultSet rs = stmt.executeQuery("SELECT * FROM transaction_failover_2");
+        for (int i = 0; i < 5; i++) {
+          assertTrue(rs.next());
+          assertEquals("test" + i, rs.getString("test"));
+        }
+        con.commit();
+        Assertions.assertTrue(con.getContext().getThreadId() != threadId);
+        assertFalse(con.getAutoCommit());
+      } else {
+        try {
+          p.executeBatch();
+          Assertions.fail();
+        } catch (SQLException e) {
+          Throwable ee = (e instanceof BatchUpdateException) ? e.getCause() : e;
+          assertTrue(ee.getMessage().contains("In progress transaction was lost"));
+        }
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/FunctionTest.java b/src/test/java/org/mariadb/jdbc/integration/FunctionTest.java
new file mode 100644
index 0000000..b10b3f8
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/FunctionTest.java
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.CallableParameterMetaData;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+
+public class FunctionTest extends Common {
+
+  @Test
+  public void basicFunction() throws SQLException {
+    // disabled for mysql : see https://bugs.mysql.com/bug.php?id=108545
+    Assumptions.assumeTrue(isMariaDBServer());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP FUNCTION IF EXISTS basic_function");
+    stmt.execute(
+        "CREATE FUNCTION basic_function (t1 INT, t2 INT unsigned) RETURNS INT DETERMINISTIC RETURN"
+            + " t1 * t2;");
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall("{? = call basic_function(?,?)}")) {
+      callableStatement.registerOutParameter(1, JDBCType.INTEGER);
+      callableStatement.setInt(2, 2);
+      callableStatement.setInt(3, 3);
+      callableStatement.execute();
+
+      assertEquals(6, callableStatement.getInt(1));
+
+      callableStatement.clearParameters();
+      callableStatement.setInt(2, 3);
+      callableStatement.setInt(3, 3);
+      callableStatement.execute();
+      assertEquals(9, callableStatement.getInt(1));
+
+      callableStatement.clearParameters();
+      assertThrowsContains(
+          SQLTransientConnectionException.class,
+          () -> callableStatement.execute(),
+          "Parameter at position 1 is not set");
+    }
+
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall("{? = call basic_function(?,?)}")) {
+      callableStatement.setInt(2, 2);
+      callableStatement.setInt(3, 3);
+      callableStatement.execute();
+      assertEquals(6, callableStatement.getInt(1));
+    }
+  }
+
+  @Test
+  public void functionWithoutArg() throws SQLException {
+    functionWithoutArg(sharedConn);
+    functionWithoutArg(sharedConnBinary);
+  }
+
+  private void functionWithoutArg(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP FUNCTION IF EXISTS no_arg_function");
+    stmt.execute("CREATE FUNCTION no_arg_function () RETURNS DOUBLE DETERMINISTIC RETURN RAND();");
+    try (CallableStatement callableStatement = con.prepareCall("{? = call no_arg_function()}")) {
+      callableStatement.registerOutParameter(1, JDBCType.DOUBLE);
+      callableStatement.execute();
+      callableStatement.getDouble(1);
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> callableStatement.registerOutParameter(2, JDBCType.DOUBLE),
+          " wrong parameter index 2");
+    }
+
+    try (CallableStatement callableStatement = con.prepareCall("{? = call no_arg_function()}")) {
+      callableStatement.execute();
+      callableStatement.getDouble(1);
+    }
+
+    try (CallableStatement callableStatement = con.prepareCall("{? = call no_arg_function}")) {
+      callableStatement.execute();
+      callableStatement.getDouble(1);
+    }
+  }
+
+  @Test
+  public void parameterMeta() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP FUNCTION IF EXISTS parameter_meta");
+    stmt.execute("CREATE FUNCTION parameter_meta () RETURNS DOUBLE DETERMINISTIC RETURN RAND();");
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall("{? = call parameter_meta()}")) {
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class,
+          () -> callableStatement.registerOutParameter(-1, JDBCType.DOUBLE),
+          "wrong parameter index");
+      callableStatement.registerOutParameter(1, JDBCType.DOUBLE);
+
+      // XPAND doesn't support I_S.parameters: https://jira.mariadb.org/browse/XPT-267
+      if (!isXpand()) {
+        CallableParameterMetaData meta =
+            (CallableParameterMetaData) callableStatement.getParameterMetaData();
+        assertEquals(org.mariadb.jdbc.ParameterMetaData.parameterModeOut, meta.getParameterMode(1));
+        assertNull(meta.getParameterName(1));
+      }
+    } finally {
+      stmt.execute("DROP FUNCTION IF EXISTS parameter_meta");
+    }
+  }
+
+  @Test
+  public void functionError() throws SQLException {
+    functionError(sharedConn);
+    functionError(sharedConnBinary);
+  }
+
+  private void functionError(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP FUNCTION IF EXISTS no_arg_function");
+    stmt.execute("CREATE FUNCTION no_arg_function () RETURNS DOUBLE DETERMINISTIC RETURN RAND();");
+    try (CallableStatement callableStatement = con.prepareCall("{? = call no_arg_function()}")) {
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class,
+          () -> callableStatement.registerOutParameter(-1, JDBCType.DOUBLE),
+          "wrong parameter index");
+      callableStatement.registerOutParameter(1, JDBCType.DOUBLE);
+
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class,
+          () -> callableStatement.registerOutParameter(-1, JDBCType.DOUBLE),
+          "wrong parameter index");
+      callableStatement.registerOutParameter(1, JDBCType.DOUBLE);
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class,
+          () -> callableStatement.registerOutParameter(2, JDBCType.DOUBLE),
+          "wrong parameter index");
+
+      callableStatement.execute();
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class,
+          () -> callableStatement.registerOutParameter(-1, JDBCType.DOUBLE),
+          "wrong parameter index");
+      callableStatement.registerOutParameter(1, JDBCType.DOUBLE);
+      if (!isXpand()) {
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> callableStatement.registerOutParameter("r", JDBCType.DOUBLE),
+            "parameter name r not found");
+      }
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class,
+          () -> callableStatement.registerOutParameter(2, JDBCType.DOUBLE),
+          "wrong parameter index");
+    }
+  }
+
+  @Test
+  public void functionToString() throws SQLException {
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall("{? = call basic_function(?,?)}")) {
+
+      assertEquals(
+          "FunctionStatement{sql:'SELECT basic_function(?,?)', parameters:[<OUT>null]}",
+          callableStatement.toString());
+      callableStatement.setLong(2, 10L);
+      callableStatement.setBytes(3, new byte[] {(byte) 'a', (byte) 'b'});
+      assertEquals(
+          "FunctionStatement{sql:'SELECT basic_function(?,?)', parameters:[<OUT>null,10,_binary"
+              + " 'ab']}",
+          callableStatement.toString());
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/GaleraTest.java b/src/test/java/org/mariadb/jdbc/integration/GaleraTest.java
new file mode 100644
index 0000000..e55ae09
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/GaleraTest.java
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import java.sql.SQLException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Connection;
+
+public class GaleraTest extends Common {
+
+  @Test
+  public void galeraAllowedStatesTest() throws SQLException {
+    if ("galera".equals(System.getenv("srv"))) {
+      try (Connection con = createCon("galeraAllowedState=4,5,6")) {
+        con.isValid(1);
+      }
+    } else {
+      try {
+        createCon("galeraAllowedState=4,5,6");
+        Assertions.fail();
+      } catch (SQLException e) {
+        Assertions.assertTrue(e.getMessage().contains("Initialization command fail"));
+        Assertions.assertTrue(
+            e.getCause()
+                .getMessage()
+                .contains("fail to validate Galera state (unknown 'wsrep_local_state' state)"));
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/GssapiAuthenticationTest.java b/src/test/java/org/mariadb/jdbc/integration/GssapiAuthenticationTest.java
new file mode 100644
index 0000000..d5df69d
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/GssapiAuthenticationTest.java
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import java.sql.*;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+
+public class GssapiAuthenticationTest extends Common {
+
+  @Test
+  public void nativePassword() throws Exception {
+    Assumptions.assumeTrue(isWindows());
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("INSTALL SONAME 'auth_gssapi'");
+    } catch (SQLException e) {
+      // eat
+    }
+    System.out.println("user name:" + System.getProperty("user.name"));
+    stmt.execute("CREATE USER " + System.getProperty("user.name") + " IDENTIFIED VIA gssapi");
+    stmt.execute("GRANT ALL PRIVILEGES ON *.* TO " + System.getProperty("user.name"));
+
+    String gssapiUrl = String.format("jdbc:mariadb://%s:%s/%s", hostname, port, database);
+    try (Connection con = DriverManager.getConnection(gssapiUrl)) {
+      con.createStatement().execute("SELECT 1");
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/LocalInfileTest.java b/src/test/java/org/mariadb/jdbc/integration/LocalInfileTest.java
new file mode 100644
index 0000000..13fa4c6
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/LocalInfileTest.java
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.sql.*;
+import java.util.Locale;
+import org.junit.jupiter.api.*;
+
+public class LocalInfileTest extends Common {
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE LocalInfileInputStreamTest(id int, test varchar(100))");
+    stmt.execute("CREATE TABLE LocalInfileInputStreamTest2(id int, test varchar(100))");
+    stmt.execute("CREATE TABLE ttlocal(id int, test varchar(100))");
+    stmt.execute("CREATE TABLE ldinfile(a varchar(10))");
+    stmt.execute(
+        "CREATE TABLE `infile`(`a` varchar(50) DEFAULT NULL, `b` varchar(50) DEFAULT NULL)"
+            + " ENGINE=InnoDB DEFAULT CHARSET=latin1");
+    stmt.execute(
+        "CREATE TABLE big_load_data_infile(id int not null primary key auto_increment, name"
+            + " char(20)) ENGINE=myisam");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS AllowMultiQueriesTest");
+    stmt.execute("DROP TABLE IF EXISTS LocalInfileInputStreamTest");
+    stmt.execute("DROP TABLE IF EXISTS LocalInfileInputStreamTest2");
+    stmt.execute("DROP TABLE IF EXISTS ttlocal");
+    stmt.execute("DROP TABLE IF EXISTS ldinfile");
+    stmt.execute("DROP TABLE IF EXISTS `infile`");
+    stmt.execute("DROP TABLE IF EXISTS big_load_data_infile");
+  }
+
+  private static boolean checkLocal() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT @@local_infile");
+    if (rs.next()) {
+      return rs.getInt(1) == 1;
+    }
+    return false;
+  }
+
+  @Test
+  public void bigLoadDataInfileTest() throws SQLException, IOException {
+    Assumptions.assumeTrue(runLongTest());
+    try (VeryLongAutoGeneratedInputStream in = new VeryLongAutoGeneratedInputStream(5000000)) {
+      try (Connection connection = createCon("&allowLocalInfile=true")) {
+        Statement statement = connection.createStatement();
+        org.mariadb.jdbc.Statement mariaDbStatement =
+            statement.unwrap(org.mariadb.jdbc.Statement.class);
+        mariaDbStatement.setLocalInfileInputStream(in);
+
+        String sql =
+            "LOAD DATA LOCAL INFILE 'dummyFileName'"
+                + " INTO TABLE big_load_data_infile "
+                + " FIELDS TERMINATED BY '\\t' ENCLOSED BY ''"
+                + " ESCAPED BY '\\\\' LINES TERMINATED BY '\\n'";
+
+        assertFalse(statement.execute(sql));
+        ResultSet rs = statement.executeQuery("select count(*) from big_load_data_infile");
+        assertTrue(rs.next());
+        assertEquals(in.numberOfRows, rs.getInt(1));
+      }
+    }
+  }
+
+  /** Custom memory conserving generator of a LOAD DATA INFILE that generates a stream. */
+  private static class VeryLongAutoGeneratedInputStream extends InputStream {
+
+    private final int numberOfRows;
+    private int currentPosInBuffer;
+    private byte[] buffer;
+    private int currentRow;
+
+    private VeryLongAutoGeneratedInputStream(int numberOfRows) {
+      this.numberOfRows = numberOfRows;
+      currentRow = 0;
+    }
+
+    @Override
+    public int read() {
+      if (currentRow > numberOfRows) {
+        return -1;
+      }
+      if (buffer != null && currentPosInBuffer >= buffer.length) {
+        buffer = null;
+      }
+      if (buffer == null) {
+        currentRow++;
+        currentPosInBuffer = 0;
+        buffer = (currentRow + "\tname" + currentRow + "\n").getBytes();
+      }
+      return buffer[currentPosInBuffer++];
+    }
+  }
+
+  @Test
+  public void streamInBatch() throws SQLException, IOException {
+    Assumptions.assumeFalse((!isMariaDBServer() && minVersion(8, 0, 3)));
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    String batch_update =
+        "LOAD DATA LOCAL INFILE 'dummy.tsv' INTO TABLE LocalInfileInputStreamTest2 (id, test)";
+    String builder = "1\thello\n2\tworld\n";
+
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
+    InputStream inputStream = new ByteArrayInputStream(builder.getBytes());
+    ((org.mariadb.jdbc.Statement) stmt).setLocalInfileInputStream(inputStream);
+    stmt.addBatch(batch_update);
+    stmt.addBatch("SET UNIQUE_CHECKS=1");
+    stmt.executeBatch();
+    stmt.addBatch(batch_update);
+    try {
+      stmt.executeBatch();
+    } catch (SQLException e) {
+      assertTrue(e.getCause().getCause() instanceof FileNotFoundException);
+    }
+
+    try (PreparedStatement prep =
+        sharedConn.prepareStatement(
+            "LOAD DATA LOCAL INFILE 'dummy.tsv' INTO TABLE LocalInfileInputStreamTest2 (id,"
+                + " test)")) {
+      inputStream = new ByteArrayInputStream(builder.getBytes());
+      ((org.mariadb.jdbc.Statement) prep).setLocalInfileInputStream(inputStream);
+      prep.addBatch();
+      prep.executeBatch();
+      try {
+        prep.addBatch();
+        prep.executeBatch();
+      } catch (SQLException e) {
+        assertTrue(e.getCause().getCause() instanceof FileNotFoundException);
+      }
+    }
+    try (PreparedStatement prep =
+        sharedConnBinary.prepareStatement(
+            "LOAD DATA LOCAL INFILE 'dummy.tsv' INTO TABLE LocalInfileInputStreamTest2 (id,"
+                + " test)")) {
+      inputStream = new ByteArrayInputStream(builder.getBytes());
+      ((org.mariadb.jdbc.Statement) prep).setLocalInfileInputStream(inputStream);
+      prep.addBatch();
+      prep.executeBatch();
+      try {
+        prep.addBatch();
+        prep.executeBatch();
+      } catch (SQLException e) {
+        assertTrue(e.getCause().getCause() instanceof FileNotFoundException);
+      }
+    }
+  }
+
+  @Test
+  public void throwExceptions() throws Exception {
+    Assumptions.assumeTrue(
+        (isMariaDBServer() || !minVersion(8, 0, 3))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+
+    // https://jira.mariadb.org/browse/XPT-270
+    Assumptions.assumeFalse(isXpand());
+
+    try (Connection con = createCon("&allowLocalInfile=false")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () ->
+              stmt.execute(
+                  "LOAD DATA LOCAL INFILE 'someFile' INTO TABLE LocalInfileInputStreamTest2 (id,"
+                      + " test)"),
+          "Local infile is disabled by connector. Enable `allowLocalInfile` to allow local infile"
+              + " commands");
+      stmt.addBatch(
+          "LOAD DATA LOCAL INFILE 'someFile' INTO TABLE LocalInfileInputStreamTest2 (id, test)");
+      stmt.addBatch("SET UNIQUE_CHECKS=1");
+
+      try {
+        stmt.executeBatch();
+        fail();
+      } catch (SQLException e) {
+        assertEquals(e.getClass(), BatchUpdateException.class);
+        assertTrue(
+            e.getMessage()
+                .contains(
+                    "Local infile is disabled by connector. Enable `allowLocalInfile` to allow"
+                        + " local infile commands"));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getMessage(), e.getMessage());
+        assertEquals(((SQLException) e.getCause()).getSQLState(), e.getSQLState());
+        assertEquals(((SQLException) e.getCause()).getErrorCode(), e.getErrorCode());
+      }
+
+      try (PreparedStatement prep =
+          con.prepareStatement(
+              "LOAD DATA LOCAL INFILE ? INTO TABLE LocalInfileInputStreamTest2 (id, test)")) {
+        prep.setString(1, "someFile");
+        Common.assertThrowsContains(
+            SQLException.class,
+            prep::execute,
+            "Local infile is disabled by connector. Enable `allowLocalInfile` to allow local infile"
+                + " commands");
+      }
+    }
+  }
+
+  @Test
+  public void wrongFile() throws Exception {
+    Assumptions.assumeTrue(checkLocal());
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    try (Connection con = createCon("allowLocalInfile")) {
+      Statement stmt = con.createStatement();
+      Common.assertThrowsContains(
+          SQLException.class,
+          () ->
+              stmt.execute(
+                  "LOAD DATA LOCAL INFILE 'someFile' INTO TABLE LocalInfileInputStreamTest2 (id,"
+                      + " test)"),
+          "Could not send file : someFile");
+      assertTrue(con.isValid(1));
+    }
+  }
+
+  @Test
+  public void unReadableFile() throws Exception {
+    Assumptions.assumeTrue(checkLocal());
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win"));
+
+    try (Connection con = createCon("allowLocalInfile")) {
+      File tempFile = File.createTempFile("hello", ".tmp");
+      tempFile.deleteOnExit();
+      tempFile.setReadable(false);
+      Statement stmt = con.createStatement();
+      Common.assertThrowsContains(
+          SQLException.class,
+          () ->
+              stmt.execute(
+                  "LOAD DATA LOCAL INFILE '"
+                      + tempFile.getCanonicalPath().replace("\\", "/")
+                      + "' INTO TABLE LocalInfileInputStreamTest2 (id, test)"),
+          "Could not send file");
+      assertTrue(con.isValid(1));
+    }
+  }
+
+  @Test
+  public void loadDataBasic() throws Exception {
+    Assumptions.assumeTrue(checkLocal());
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    File temp = File.createTempFile("dummyloadDataBasic", ".txt");
+    try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp))) {
+      bw.write("1\thello2\n2\tworld\n");
+    }
+
+    try (Connection con = createCon("allowLocalInfile")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
+      stmt.execute(
+          "LOAD DATA LOCAL INFILE '"
+              + temp.getCanonicalPath().replace("\\", "/")
+              + "' INTO TABLE LocalInfileInputStreamTest2 (id, test)");
+      ResultSet rs = stmt.executeQuery("SELECT * FROM LocalInfileInputStreamTest2");
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt(1));
+      assertEquals("hello2", rs.getString(2));
+      assertTrue(rs.next());
+      assertEquals(2, rs.getInt(1));
+      assertEquals("world", rs.getString(2));
+      while (rs.next()) {
+        System.out.println(rs.getString(2));
+      }
+      assertFalse(rs.next());
+
+      stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
+      stmt.addBatch(
+          "LOAD DATA LOCAL INFILE '"
+              + temp.getCanonicalPath().replace("\\", "/")
+              + "' INTO TABLE LocalInfileInputStreamTest2 (id, test)");
+      stmt.addBatch("SET UNIQUE_CHECKS=1");
+      stmt.executeBatch();
+
+      rs = stmt.executeQuery("SELECT * FROM LocalInfileInputStreamTest2");
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt(1));
+      assertEquals("hello2", rs.getString(2));
+      assertTrue(rs.next());
+      assertEquals(2, rs.getInt(1));
+      assertEquals("world", rs.getString(2));
+      assertFalse(rs.next());
+    } finally {
+      temp.delete();
+    }
+  }
+
+  @Test
+  public void loadDataValidationFails() throws Exception {
+    Assumptions.assumeTrue(checkLocal());
+    loadDataValidationFails(false);
+    loadDataValidationFails(true);
+  }
+
+  public void loadDataValidationFails(boolean prepStmt) throws Exception {
+    File temp = File.createTempFile("dummy", ".txt");
+    File tempXml = File.createTempFile("xmldummy", ".txt");
+
+    try (Connection con = createCon("&allowLocalInfile&useServerPrepStmts=" + prepStmt)) {
+      try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp))) {
+        bw.write("1\thello\n2\tworld\n");
+      }
+      try (BufferedWriter bw = new BufferedWriter(new FileWriter(tempXml))) {
+        bw.write("<row id=\"1\" test=\"hello\" />\n<row id=\"2\" test=\"world\" />\n");
+      }
+      try (PreparedStatement prep =
+          con.prepareStatement(
+              "LOAD DATA LOCAL INFILE ? INTO TABLE LocalInfileInputStreamTest2 (id, test)")) {
+        prep.setString(1, temp.getCanonicalPath().replace("\\", "/"));
+        prep.execute();
+      }
+      try (PreparedStatement prep =
+          con.prepareStatement(
+              "LOAD XML LOCAL INFILE ? INTO TABLE LocalInfileInputStreamTest2 (id, test)")) {
+        prep.setString(1, tempXml.getCanonicalPath().replace("\\", "/"));
+        prep.execute();
+      }
+      try (PreparedStatement prep =
+          con.prepareStatement(
+              "/* test */ LOAD  DATA LOCAL INFILE 'j' INTO TABLE LocalInfileInputStreamTest2 (id,"
+                  + " test)")) {
+        assertThrowsContains(SQLException.class, () -> prep.execute(), "Could not send file : j");
+      }
+      // special test comment inside LOAD DATA LOCAL are not checked, resulting in error
+      try (PreparedStatement prep =
+          con.prepareStatement(
+              "LOAD /**g*/ DATA LOCAL INFILE 'h' INTO TABLE LocalInfileInputStreamTest2 (id,"
+                  + " test)")) {
+        assertThrowsContains(
+            SQLException.class,
+            () -> prep.execute(),
+            "LOAD DATA LOCAL INFILE asked for file 'h' that doesn't correspond to initial query ");
+      }
+      // ensure connection state after errors
+      ResultSet rs = con.createStatement().executeQuery("SELECT 1");
+      rs.next();
+      assertEquals(1, rs.getInt(1));
+    } finally {
+      temp.delete();
+      tempXml.delete();
+    }
+  }
+
+  @Test
+  public void loadDataInfileEmpty() throws SQLException, IOException {
+    Assumptions.assumeTrue(
+        (isMariaDBServer() || !minVersion(8, 0, 3))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+    // Create temp file.
+    File temp = File.createTempFile("validateInfile", ".tmp");
+    try (Connection connection = createCon("&allowLocalInfile=true")) {
+      Statement st = connection.createStatement();
+      st.execute(
+          "LOAD DATA LOCAL INFILE '"
+              + temp.getAbsolutePath().replace('\\', '/')
+              + "' INTO TABLE ldinfile");
+      try (ResultSet rs = st.executeQuery("SELECT * FROM ldinfile")) {
+        assertFalse(rs.next());
+      }
+    } finally {
+      temp.delete();
+    }
+  }
+
+  private File createTmpData(long recordNumber) throws Exception {
+    File file = File.createTempFile("infile" + recordNumber, ".tmp");
+
+    // write it
+    try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
+      // Every row is 8 bytes to make counting easier
+      for (long i = 0; i < recordNumber; i++) {
+        writer.write("\"a\",\"b\"");
+        writer.write("\n");
+      }
+    }
+
+    return file;
+  }
+
+  private void checkBigLocalInfile(long fileSize) throws Exception {
+    long recordNumber = fileSize / 8;
+    try (Connection connection = createCon("allowLocalInfile")) {
+      Statement stmt = connection.createStatement();
+      stmt.execute("truncate `infile`");
+      File file = createTmpData(recordNumber);
+      int insertNumber =
+          stmt.executeUpdate(
+              "LOAD DATA LOCAL INFILE '"
+                  + file.getCanonicalPath().replace("\\", "/")
+                  + "' "
+                  + "INTO TABLE `infile` "
+                  + "COLUMNS TERMINATED BY ',' ENCLOSED BY '\\\"' ESCAPED BY '\\\\' "
+                  + "LINES TERMINATED BY '\\n' (`a`, `b`)");
+      assertEquals(insertNumber, recordNumber);
+      file.delete();
+      stmt.setFetchSize(1000); // to avoid using too much memory for tests
+      try (ResultSet rs = stmt.executeQuery("SELECT * FROM `infile`")) {
+        for (int i = 0; i < recordNumber; i++) {
+          assertTrue(rs.next());
+          assertEquals("a", rs.getString(1));
+          assertEquals("b", rs.getString(2));
+        }
+        assertFalse(rs.next());
+      }
+    }
+  }
+
+  @Test
+  public void testSmallBigLocalInfileInputStream() throws Exception {
+    Assumptions.assumeTrue(
+        (isMariaDBServer() || !minVersion(8, 0, 3))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+    checkBigLocalInfile(256);
+  }
+
+  @Test
+  public void test2xBigLocalInfileInputStream() throws Exception {
+    Assumptions.assumeTrue(
+        ((isMariaDBServer() || !minVersion(8, 0, 3)) && runLongTest())
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+    checkBigLocalInfile(16777216 * 2);
+  }
+
+  @Test
+  public void testMoreThanMaxAllowedPacketLocalInfileInputStream() throws Exception {
+    Assumptions.assumeTrue(
+        (isMariaDBServer() || !minVersion(8, 0, 3))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+    Assumptions.assumeTrue(runLongTest());
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("select @@max_allowed_packet");
+    assertTrue(rs.next());
+    long maxAllowedPacket = rs.getLong(1);
+    Assumptions.assumeTrue(maxAllowedPacket < 100_000_000);
+    checkBigLocalInfile(maxAllowedPacket + 1024);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/LoggingTest.java b/src/test/java/org/mariadb/jdbc/integration/LoggingTest.java
new file mode 100644
index 0000000..6e333cc
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/LoggingTest.java
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.FileAppender;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLException;
+import javax.security.auth.x500.X500Principal;
+import javax.sql.PooledConnection;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.MariaDbPoolDataSource;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.tls.HostnameVerifier;
+import org.slf4j.LoggerFactory;
+
+public class LoggingTest extends Common {
+
+  @Test
+  void basicLogging() throws Exception {
+    Assumptions.assumeTrue(isMariaDBServer());
+    File tempFile = File.createTempFile("log", ".tmp");
+
+    Logger logger = (Logger) LoggerFactory.getLogger("org.mariadb.jdbc");
+    Level initialLevel = logger.getLevel();
+    logger.setLevel(Level.TRACE);
+    logger.setAdditive(false);
+    logger.detachAndStopAllAppenders();
+
+    LoggerContext context = new LoggerContext();
+    FileAppender<ILoggingEvent> fa = new FileAppender<>();
+    fa.setName("FILE");
+    fa.setImmediateFlush(true);
+    PatternLayoutEncoder pa = new PatternLayoutEncoder();
+    pa.setPattern("%r %5p %c [%t] - %m%n");
+    pa.setContext(context);
+    pa.start();
+    fa.setEncoder(pa);
+
+    fa.setFile(tempFile.getPath());
+    fa.setAppend(true);
+    fa.setContext(context);
+    fa.start();
+
+    logger.addAppender(fa);
+
+    try (Connection conn = createCon()) {
+      Statement stmt = conn.createStatement();
+      stmt.execute("SELECT 1");
+    }
+    try (Connection conn = createCon("useCompression=true")) {
+      Statement stmt = conn.createStatement();
+      stmt.execute("SELECT 1");
+    }
+
+    MariaDbPoolDataSource ds =
+        new MariaDbPoolDataSource(
+            mDefUrl + "&sessionVariables=wait_timeout=1&maxIdleTime=2&testMinRemovalDelay=2");
+    Thread.sleep(4000);
+    PooledConnection pc = ds.getPooledConnection();
+    pc.getConnection().isValid(1);
+    pc.close();
+    ds.close();
+    try {
+      String contents = new String(Files.readAllBytes(Paths.get(tempFile.getPath())));
+      String selectOne =
+          "       +--------------------------------------------------+\n"
+              + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+              + "+------+--------------------------------------------------+------------------+\n"
+              + "|000000| 09 00 00 00 03 53 45 4C  45 43 54 20 31          | .....SELECT 1    |\n"
+              + "+------+--------------------------------------------------+------------------+\n";
+      Assertions.assertTrue(
+          contents.contains(selectOne) || contents.contains(selectOne.replace("\r\n", "\n")),
+          contents);
+      String rowResult =
+          "       +--------------------------------------------------+\n"
+              + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+              + "+------+--------------------------------------------------+------------------+\n"
+              + "|000000| 02 00 00 03 01 31                                | .....1           |\n"
+              + "+------+--------------------------------------------------+------------------+\n";
+      String rowResultWithEof =
+          "       +--------------------------------------------------+\n"
+              + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+              + "+------+--------------------------------------------------+------------------+\n"
+              + "|000000| 02 00 00 04 01 31                                | .....1           |\n"
+              + "+------+--------------------------------------------------+------------------+\n";
+      Assertions.assertTrue(
+          contents.contains(rowResult)
+              || contents.contains(rowResult.replace("\r\n", "\n"))
+              || contents.contains(rowResultWithEof)
+              || contents.contains(rowResultWithEof.replace("\r\n", "\n")),
+          contents);
+
+      Assertions.assertTrue(
+          contents.contains("pool MariaDB-pool new physical connection ")
+              && contents.contains("created (total:1, active:0, pending:0)"),
+          contents);
+      Assertions.assertTrue(
+          contents.contains("pool MariaDB-pool connection ")
+              && contents.contains("removed due to inactivity"),
+          contents);
+    } catch (IOException e) {
+      e.printStackTrace();
+      Assertions.fail();
+    } finally {
+      logger.setLevel(initialLevel);
+      logger.detachAppender(fa);
+    }
+  }
+
+  @Test
+  void certLogging() throws Exception {
+    File tempFile = File.createTempFile("log", ".tmp");
+
+    Logger logger = (Logger) LoggerFactory.getLogger("org.mariadb.jdbc");
+    Level initialLevel = logger.getLevel();
+    logger.setLevel(Level.TRACE);
+    logger.setAdditive(false);
+    logger.detachAndStopAllAppenders();
+
+    LoggerContext context = new LoggerContext();
+    FileAppender<ILoggingEvent> fa = new FileAppender<>();
+    fa.setName("FILE");
+    fa.setImmediateFlush(true);
+    PatternLayoutEncoder pa = new PatternLayoutEncoder();
+    pa.setPattern("%r %5p %c [%t] - %m%n");
+    pa.setContext(context);
+    pa.start();
+    fa.setEncoder(pa);
+
+    fa.setFile(tempFile.getPath());
+
+    fa.setAppend(true);
+    fa.setContext(context);
+    fa.start();
+
+    logger.addAppender(fa);
+
+    String certString =
+        ""
+            + "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDfDCCAmSgAwIBAgIURZJQVOWv+oaj+MLlHWc1B0TnOaowDQYJKoZIhvcNAQEL\n"
+            + "BQAwUjELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYDVQQHDAJTWjESMBAG\n"
+            + "A1UECgwJQWNtZSxJbmMuMRUwEwYDVQQDDAxBY21lIFJvb3QgQ0EwIBcNMjEwMzMw\n"
+            + "MDkwODAxWhgPMjEyMTAzMDYwOTA4MDFaMFMxCzAJBgNVBAYTAkNOMQswCQYDVQQI\n"
+            + "DAJHRDELMAkGA1UEBwwCU1oxEjAQBgNVBAoMCUFjbWUsSW5jLjEWMBQGA1UEAwwN\n"
+            + "Ki5tYXJpYWRiLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAJ\n"
+            + "xqbqTGmwO5n3kVd6QJPRSh+0M1HIQacyM/tkE7jLw3725/KtknuwuFbPpxKyTCLC\n"
+            + "IoNx4yaBbmx783OPP3pokXTWiMdrVZdLltBNamNzekNFN4YhR5oN479M5cKgrk94\n"
+            + "Ud+ql0NN5FscrSQ0fSdJf0idJMqThro1MJVp9rp5cdCba6/lKyDbdOybe5f7rmrg\n"
+            + "+37J+src67+rqwVT8ZwZgLTGDf4X9OSIzyw6+PCWYWr89aurrOuOyqA3QqXVRZa/\n"
+            + "IxOMHIdzXMgLN6+HduwdZ+DNv1NPT2MDlRQvOnDop3NoEVKWekOTv50LbKRgWTYO\n"
+            + "TK/dfcsDpZmdyHv7pb8CAwEAAaNHMEUwQwYDVR0RBDwwOoIVbG9jYWxob3N0Lmxv\n"
+            + "Y2FsZG9tYWlugglsb2NhbGhvc3SHBH8AAAGHECABDbg5AjRoAAAAAAAABEMwDQYJ\n"
+            + "KoZIhvcNAQELBQADggEBAHsiJz9cpmL8BTa/o10S+pmap3iOnYYuJT0llCRLJ+Ji\n"
+            + "msO2niyIwqCJHMLcEABCENJt0HDOEKlnunVgc+X/6K8DnPrYhfWQbYI/dwUBoSIQ\n"
+            + "siK/yKW0q+S+YjCVpNMA3iMfhJ9Qe9LDO+xdCBhzplgrV8YwG+J2FUNbZfvl5cML\n"
+            + "TjKLWrWo9dgZyH/7mjwryRzswfUfr/lRARCyrMotaXfYmjPjwTSRc0aPGrEjs3ns\n"
+            + "WMtimgh7Zw3Tbxc51miz9CRy767lq/9BGTdeBLmW0EXssIJb9uO0Ht3C/Pqy0ojk\n"
+            + "8e1eYtofjTsqWHZ1s2LhtT0HvXdL6BnWP9GWc/zxiKM=\n"
+            + "-----END CERTIFICATE-----\n";
+    CertificateFactory cf = CertificateFactory.getInstance("X.509");
+    X509Certificate cert =
+        (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certString.getBytes()));
+
+    assertEquals(
+        new X500Principal("CN=*.mariadb.org, O=\"Acme,Inc.\", L=SZ, ST=GD, C=CN"),
+        cert.getSubjectX500Principal());
+    HostnameVerifier.verify("localhost", cert, -1);
+    HostnameVerifier.verify("localhost.localdomain", cert, -1);
+    verifyExceptionEqual(
+        "local.host",
+        cert,
+        "DNS host \"local.host\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
+
+    HostnameVerifier.verify("127.0.0.1", cert, -1);
+    verifyExceptionEqual(
+        "127.0.0.2",
+        cert,
+        "IPv4 host \"127.0.0.2\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
+
+    HostnameVerifier.verify("2001:db8:3902:3468:0:0:0:443", cert, -1);
+    verifyExceptionEqual(
+        "2001:db8:1::",
+        cert,
+        "IPv6 host \"2001:db8:1::\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
+    try {
+      String contents = new String(Files.readAllBytes(Paths.get(tempFile.getPath())));
+
+      assertTrue(
+          contents.contains(
+              "DNS verification of hostname : type=DNS value=localhost.localdomain to local.host"));
+      assertTrue(
+          contents.contains(
+              "IPv4 verification of hostname : type=IP value=127.0.0.1 to 127.0.0.2"));
+      assertTrue(
+          contents.contains(
+              "IPv6 verification of hostname : type=IP value=2001:db8:3902:3468:0:0:0:443 to"
+                  + " 2001:db8:1::"));
+
+      logger.setLevel(initialLevel);
+      logger.detachAppender(fa);
+    } catch (IOException e) {
+      e.printStackTrace();
+      Assertions.fail();
+    }
+  }
+
+  private void verifyExceptionEqual(String host, X509Certificate cert, String exceptionMessage) {
+    Exception e =
+        Assertions.assertThrows(SSLException.class, () -> HostnameVerifier.verify(host, cert, -1));
+    Assertions.assertTrue(
+        e.getMessage().contains(exceptionMessage), "real message:" + e.getMessage());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/MultiHostTest.java b/src/test/java/org/mariadb/jdbc/integration/MultiHostTest.java
new file mode 100644
index 0000000..cda7d8e
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/MultiHostTest.java
@@ -0,0 +1,576 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.sql.*;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.integration.tools.TcpProxy;
+
+public class MultiHostTest extends Common {
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    createSequenceTables();
+  }
+
+  @Test
+  public void failoverReadonlyToMaster() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try (Connection con = createProxyConKeep("&waitReconnectTimeout=300&deniedListTimeout=300")) {
+      long primaryThreadId = con.getThreadId();
+      con.setReadOnly(true);
+      long replicaThreadId = con.getThreadId();
+      assertTrue(primaryThreadId != replicaThreadId);
+
+      con.setReadOnly(false);
+      assertEquals(primaryThreadId, con.getThreadId());
+      con.setReadOnly(true);
+      assertEquals(replicaThreadId, con.getThreadId());
+      proxy.restart(250);
+
+      con.isValid(1);
+      assertEquals(primaryThreadId, con.getThreadId());
+    }
+  }
+
+  @Test
+  public void ensureReadOnlyOnReplica() throws Exception {
+    // mariadb1.example.com, mariadb2.example.com and mariadb3.example.com DNS alias must be defined
+    Assumptions.assumeTrue(
+        !isWindows()
+            && !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !isXpand());
+
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    String url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//mariadb1.example.com:%s,mariadb2.example.com:%s,mariadb3.example.com:%s/",
+                hostAddress.port, hostAddress.port, hostAddress.port));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:replication:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+    try {
+      int replica1 = 0;
+      int replica2 = 0;
+      for (int i = 0; i < 100; i++) {
+        try (Connection con =
+            (Connection)
+                DriverManager.getConnection(
+                    url + "&waitReconnectTimeout=30&deniedListTimeout=300")) {
+          assertTrue(con.__test_host().contains("primary"));
+          con.setReadOnly(true);
+          assertTrue(con.__test_host().contains("replica"));
+          if (con.__test_host().contains("mariadb2")) {
+            replica1++;
+          }
+          if (con.__test_host().contains("mariadb3")) {
+            replica2++;
+          }
+        }
+      }
+
+      assertTrue(
+          replica1 > 35, "value replica1/replicat2 aren't right : " + replica1 + "/" + replica2);
+      assertTrue(
+          replica2 > 35, "value replica1/replicat2 aren't right : " + replica1 + "/" + replica2);
+    } catch (SQLNonTransientConnectionException e) {
+      // eat
+    }
+  }
+
+  @Test
+  public void readOnly() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !isXpand());
+    try (Connection con = createProxyConKeep("&waitReconnectTimeout=300&deniedListTimeout=300")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("DROP TABLE IF EXISTS testReadOnly");
+      stmt.execute("CREATE TABLE testReadOnly(id int)");
+      con.setAutoCommit(false);
+      con.setReadOnly(true);
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> stmt.execute("INSERT INTO testReadOnly values (2)"),
+          "Cannot execute statement in a READ ONLY transaction");
+      con.setReadOnly(false);
+      stmt.execute("DROP TABLE testReadOnly");
+    }
+  }
+
+  @Test
+  public void syncState() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try (Connection con = createProxyConKeep("")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("CREATE DATABASE IF NOT EXISTS sync");
+      con.setCatalog("sync");
+      con.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);
+      con.setReadOnly(true);
+      assertEquals("sync", con.getCatalog());
+      assertEquals(java.sql.Connection.TRANSACTION_SERIALIZABLE, con.getTransactionIsolation());
+      con.setReadOnly(true);
+      con.setReadOnly(false);
+      assertEquals(java.sql.Connection.TRANSACTION_SERIALIZABLE, con.getTransactionIsolation());
+      con.setTransactionIsolation(java.sql.Connection.TRANSACTION_READ_COMMITTED);
+      con.setReadOnly(true);
+      assertEquals(java.sql.Connection.TRANSACTION_READ_COMMITTED, con.getTransactionIsolation());
+      con.setTransactionIsolation(java.sql.Connection.TRANSACTION_READ_UNCOMMITTED);
+      con.setReadOnly(false);
+      assertEquals(java.sql.Connection.TRANSACTION_READ_UNCOMMITTED, con.getTransactionIsolation());
+      con.setTransactionIsolation(java.sql.Connection.TRANSACTION_REPEATABLE_READ);
+      con.setReadOnly(true);
+      assertEquals(java.sql.Connection.TRANSACTION_REPEATABLE_READ, con.getTransactionIsolation());
+    } finally {
+      sharedConn.createStatement().execute("DROP DATABASE IF EXISTS sync");
+    }
+  }
+
+  @Test
+  public void replicaNotSet() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    String url = mDefUrl.replaceAll("jdbc:mariadb:", "jdbc:mariadb:replication:");
+    try (java.sql.Connection con = DriverManager.getConnection(url + "&waitReconnectTimeout=20")) {
+      con.isValid(1);
+      con.setReadOnly(true);
+      con.isValid(1);
+      // force reconnection try
+      Thread.sleep(50);
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void closedConnectionMulti() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    String url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//address=(host=localhost)(port=9999)(type=master),address=(host=%s)(port=%s)(type=master)/",
+                hostAddress.host, hostAddress.port));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:sequential:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=4&connectTimeout=500&useServerPrepStmts&cachePrepStmts=false");
+    testClosedConn(con);
+
+    url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//%s:%s,%s,%s/",
+                hostAddress.host, hostAddress.port, hostAddress.host, hostAddress.port));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:replication:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=4&connectTimeout=500&useServerPrepStmts&cachePrepStmts=false");
+    testClosedConn(con);
+  }
+
+  private void testClosedConn(Connection con) throws SQLException {
+    PreparedStatement prep = con.prepareStatement("SELECT ?");
+    PreparedStatement prep2 = con.prepareStatement("SELECT 1, ?");
+    prep2.setString(1, "1");
+    prep2.execute();
+    Statement stmt = con.createStatement();
+    stmt.setFetchSize(1);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10");
+    rs.next();
+
+    con.close();
+
+    prep.setString(1, "1");
+    assertThrowsContains(SQLException.class, () -> prep.execute(), "Connection is closed");
+    assertThrowsContains(SQLException.class, () -> prep2.execute(), "Connection is closed");
+    assertThrowsContains(
+        SQLException.class, () -> rs.next(), "Error while streaming resultSet data");
+    assertThrowsContains(SQLException.class, () -> prep2.close(), "Connection is closed");
+    con.close();
+    assertThrowsContains(SQLException.class, () -> con.abort(null), "Connection is closed");
+    assertNotNull(con.getClient().getHostAddress());
+    assertThrowsContains(
+        SQLException.class,
+        () -> con.getClient().readStreamingResults(null, 0, 0, 0, 0, true),
+        "Connection is closed");
+    con.getClient().reset();
+  }
+
+  @Test
+  public void masterFailover() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try {
+      proxy = new TcpProxy(hostAddress.host, hostAddress.port);
+    } catch (IOException i) {
+      throw new SQLException("proxy error", i);
+    }
+
+    String url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//address=(host=localhost)(port=9999)(type=master),address=(host=localhost)(port=%s)(type=master),address=(host=%s)(port=%s)(type=master)/",
+                proxy.getLocalPort(), hostAddress.host, hostAddress.port));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:sequential:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    try (Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&deniedListTimeout=300&retriesAllDown=4&connectTimeout=20&deniedListTimeout=20")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("SET @con=1");
+      proxy.restart(50);
+      con.isValid(1000);
+    }
+
+    Thread.sleep(100);
+    // same in transaction
+    try (Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&waitReconnectTimeout=300&retriesAllDown=10&connectTimeout=20&deniedListTimeout=20")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("START TRANSACTION");
+      stmt.execute("SET @con=1");
+
+      proxy.restart(100);
+      try {
+        ResultSet rs = stmt.executeQuery("SELECT @con");
+        if (rs.next()) {
+          System.out.println("Resultset res:" + rs.getString(1));
+        }
+        fail("must have thrown exception");
+      } catch (SQLTransientConnectionException e) {
+        assertTrue(e.getMessage().contains("In progress transaction was lost"));
+      }
+    }
+
+    Thread.sleep(50);
+    // testing blacklisted
+    try (Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url + "&retriesAllDown=4&connectTimeout=20&deniedListTimeout=20")) {
+      Statement stmt = con.createStatement();
+      con.setAutoCommit(false);
+      stmt.execute("START TRANSACTION");
+      stmt.execute("SET @con=1");
+
+      proxy.restart(50);
+      try {
+        ResultSet rs = stmt.executeQuery("SELECT @con");
+        rs.next();
+        assertEquals(1, rs.getInt(1));
+      } catch (SQLException e) {
+        assertTrue(e.getMessage().contains("In progress transaction was lost"));
+      }
+    }
+    Thread.sleep(50);
+    // with transaction replay
+    try (Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&transactionReplay=true&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=4&connectTimeout=20")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("DROP TABLE IF EXISTS testReplay");
+      stmt.execute("CREATE TABLE testReplay(id INT)");
+      stmt.execute("INSERT INTO testReplay VALUE (1)");
+      con.setAutoCommit(false);
+      stmt.execute("START TRANSACTION");
+      stmt.execute("INSERT INTO testReplay VALUE (2)");
+      try (PreparedStatement prep = con.prepareStatement("INSERT INTO testReplay VALUE (?)")) {
+        prep.setInt(1, 3);
+        prep.execute();
+      }
+
+      try (PreparedStatement prep = con.prepareStatement("INSERT INTO testReplay VALUE (?)")) {
+        prep.setInt(1, 4);
+        prep.execute();
+        proxy.restart(50);
+        prep.setInt(1, 5);
+        prep.execute();
+      }
+
+      ResultSet rs = stmt.executeQuery("SELECT * from testReplay");
+      rs.next();
+      assertEquals(1, rs.getInt(1));
+      rs.next();
+      assertEquals(2, rs.getInt(1));
+      rs.next();
+      assertEquals(3, rs.getInt(1));
+      rs.next();
+      assertEquals(4, rs.getInt(1));
+      rs.next();
+      assertEquals(5, rs.getInt(1));
+      assertFalse(rs.next());
+      stmt.execute("DROP TABLE IF EXISTS testReplay");
+    }
+  }
+
+  @Test
+  public void masterStreamingFailover() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try {
+      proxy = new TcpProxy(hostAddress.host, hostAddress.port);
+    } catch (IOException i) {
+      throw new SQLException("proxy error", i);
+    }
+
+    String url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//address=(host=localhost)(port=%s)(type=master)/", proxy.getLocalPort()));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:sequential:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&allowMultiQueries&transactionReplay=true&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=40&connectTimeout=500&useReadAheadInput=false");
+    long threadId = con.getThreadId();
+    Statement stmt = con.createStatement();
+    stmt.setFetchSize(2);
+    ResultSet rs =
+        stmt.executeQuery("SELECT * FROM sequence_1_to_10; SELECT * FROM sequence_1_to_10000");
+    rs.next();
+    assertEquals(1, rs.getInt(1));
+    proxy.restart(50);
+    Statement stmt2 = con.createStatement();
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt2.executeQuery("SELECT * from sequence_1_to_10"),
+        "Socket error during result streaming");
+    assertNotEquals(threadId, con.getThreadId());
+
+    // additional small test
+    assertEquals(0, con.getNetworkTimeout());
+    con.setNetworkTimeout(Runnable::run, 10);
+    assertEquals(10, con.getNetworkTimeout());
+
+    con.setReadOnly(true);
+    con.close();
+    Common.assertThrowsContains(
+        SQLNonTransientConnectionException.class,
+        () -> con.setReadOnly(false),
+        "Connection is closed");
+    Common.assertThrowsContains(
+        SQLNonTransientConnectionException.class,
+        () -> con.abort(Runnable::run),
+        "Connection is closed");
+
+    Connection con2 =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&allowMultiQueries&transactionReplay=true&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=40&connectTimeout=500&useReadAheadInput=false");
+    con2.abort(Runnable::run);
+  }
+
+  @Test
+  public void masterReplicationFailover() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try {
+      proxy = new TcpProxy(hostAddress.host, hostAddress.port);
+    } catch (IOException i) {
+      throw new SQLException("proxy error", i);
+    }
+
+    String url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//localhost:%s,%s:%s/", proxy.getLocalPort(), hostAddress.host, hostAddress.port));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:replication:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    try (Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=4&connectTimeout=500")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("SET @con=1");
+      con.setReadOnly(true);
+      con.isValid(1);
+      proxy.restart(50);
+      Thread.sleep(20);
+      con.setReadOnly(false);
+
+      assertThrowsContains(
+          SQLTransientConnectionException.class,
+          () -> stmt.executeQuery("SELECT @con"),
+          "Driver has reconnect connection after a communications link failure with");
+    }
+
+    // never reconnect
+    try (Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=4&connectTimeout=500")) {
+      Statement stmt = con.createStatement();
+      stmt.execute("SET @con=1");
+      con.setReadOnly(true);
+      con.isValid(1);
+      proxy.stop();
+      Thread.sleep(20);
+      con.setReadOnly(false);
+      assertFalse(con.isValid(1));
+      assertThrows(SQLException.class, () -> stmt.execute("SELECT 1"));
+    }
+  }
+
+  @Test
+  public void masterReplicationStreamingFailover() throws Exception {
+    Assumptions.assumeTrue(
+        isMariaDBServer()
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try {
+      proxy = new TcpProxy(hostAddress.host, hostAddress.port);
+    } catch (IOException i) {
+      throw new SQLException("proxy error", i);
+    }
+
+    String url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//address=(host=localhost)(port=%s)(type=primary),address=(host=%s)(port=%s)(type=replica)/",
+                proxy.getLocalPort(), hostAddress.host, hostAddress.port));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:replication:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    Connection con =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&allowMultiQueries&transactionReplay=true&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=40&connectTimeout=500&useReadAheadInput=false");
+    long threadId = con.getThreadId();
+    Statement stmt = con.createStatement();
+    stmt.setFetchSize(2);
+    ResultSet rs =
+        stmt.executeQuery("SELECT * FROM sequence_1_to_10; SELECT * FROM sequence_1_to_10000");
+    rs.next();
+    assertEquals(1, rs.getInt(1));
+    proxy.restart(50);
+    Statement stmt2 = con.createStatement();
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt2.executeQuery("SELECT * from sequence_1_to_10"),
+        "Socket error during result streaming");
+    assertNotEquals(threadId, con.getThreadId());
+
+    // additional small test
+    assertEquals(0, con.getNetworkTimeout());
+    con.setNetworkTimeout(Runnable::run, 10);
+    assertEquals(10, con.getNetworkTimeout());
+
+    con.setReadOnly(true);
+    con.close();
+    Common.assertThrowsContains(
+        SQLNonTransientConnectionException.class,
+        () -> con.setReadOnly(false),
+        "Connection is closed");
+    Common.assertThrowsContains(
+        SQLNonTransientConnectionException.class,
+        () -> con.abort(Runnable::run),
+        "Connection is closed");
+
+    Connection con2 =
+        (Connection)
+            DriverManager.getConnection(
+                url
+                    + "&allowMultiQueries&transactionReplay=true&waitReconnectTimeout=300&deniedListTimeout=300&retriesAllDown=40&connectTimeout=500&useReadAheadInput=false");
+    con2.abort(Runnable::run);
+  }
+
+  public Connection createProxyConKeep(String opts) throws SQLException {
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try {
+      proxy = new TcpProxy(hostAddress.host, hostAddress.port);
+    } catch (IOException i) {
+      throw new SQLException("proxy error", i);
+    }
+
+    String url =
+        mDefUrl.replaceAll(
+            "//([^/]*)/",
+            String.format(
+                "//%s:%s,localhost:%s/", hostAddress.host, hostAddress.port, proxy.getLocalPort()));
+    url = url.replaceAll("jdbc:mariadb:", "jdbc:mariadb:replication:");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    return (Connection) DriverManager.getConnection(url + opts);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/MultiPacketTest.java b/src/test/java/org/mariadb/jdbc/integration/MultiPacketTest.java
new file mode 100644
index 0000000..08a4fd2
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/MultiPacketTest.java
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+
+public class MultiPacketTest extends Common {
+  private static final char[] arr2 = new char[17 * 1024 * 1024];
+
+  static {
+    for (int pos = 0; pos < arr2.length; pos++) {
+      arr2[pos] = (char) ('A' + (pos % 60));
+    }
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    Assumptions.assumeTrue(getMaxAllowedPacket() > 19 * 1024 * 1024);
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS multiPacketTest");
+    stmt.execute("CREATE TABLE multiPacketTest (t1 MEDIUMTEXT, t2 LONGTEXT)");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE IF EXISTS multiPacketTest");
+  }
+
+  @Test
+  public void bigByteSend() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE multiPacketTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        sharedConnBinary.prepareStatement("INSERT INTO multiPacketTest VALUE (?,?)")) {
+      prep.setString(1, new String(arr2, 0, 128 * 1024 - 24));
+      prep.setByte(2, (byte) 2);
+      prep.execute();
+    }
+    ResultSet rs = stmt.executeQuery("SELECT t2 FROM multiPacketTest");
+    assertTrue(rs.next(), "expected rows");
+    assertEquals("2", rs.getString(1));
+  }
+
+  @Test
+  public void bigByte2Send() throws Throwable {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE multiPacketTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        sharedConnBinary.prepareStatement("INSERT INTO multiPacketTest VALUE (?,?)")) {
+      prep.setString(1, "test1");
+      prep.setByte(2, (byte) 1);
+      prep.execute();
+      prep.setString(1, new String(arr2, 0, 16 * 1024 * 1024 - 21));
+      prep.setByte(2, (byte) 2);
+      prep.execute();
+    }
+    ResultSet rs = stmt.executeQuery("SELECT t2 FROM multiPacketTest");
+    assertTrue(rs.next(), "expected rows");
+    assertTrue(rs.next());
+    assertEquals("2", rs.getString(1));
+  }
+
+  @Test
+  public void bigShortSend() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE multiPacketTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        sharedConnBinary.prepareStatement("INSERT INTO multiPacketTest VALUE (?,?)")) {
+      prep.setString(1, new String(arr2, 0, 16 * 1024 * 1024 - 21));
+      prep.setShort(2, (short) 2);
+      prep.execute();
+    }
+    ResultSet rs = stmt.executeQuery("SELECT t2 FROM multiPacketTest");
+    assertTrue(rs.next(), "expected rows");
+    assertEquals("2", rs.getString(1));
+  }
+
+  @Test
+  public void bigIntSend() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE multiPacketTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        sharedConnBinary.prepareStatement("INSERT INTO multiPacketTest VALUE (?,?)")) {
+      prep.setString(1, new String(arr2, 0, 16 * 1024 * 1024 - 21));
+      prep.setInt(2, 2);
+      prep.execute();
+    }
+    ResultSet rs = stmt.executeQuery("SELECT t2 FROM multiPacketTest");
+    assertTrue(rs.next(), "expected rows");
+    assertEquals("2", rs.getString(1));
+  }
+
+  @Test
+  public void bigLongSend() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE multiPacketTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        sharedConnBinary.prepareStatement("INSERT INTO multiPacketTest VALUE (?,?)")) {
+      prep.setString(1, new String(arr2, 0, 16 * 1024 * 1024 - 21));
+      prep.setLong(2, 2L);
+      prep.execute();
+    }
+    ResultSet rs = stmt.executeQuery("SELECT t2 FROM multiPacketTest");
+    assertTrue(rs.next(), "expected rows");
+    assertEquals("2", rs.getString(1));
+  }
+
+  @Test
+  public void bigStringSend() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE multiPacketTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        sharedConnBinary.prepareStatement("INSERT INTO multiPacketTest VALUE (?,?)")) {
+      prep.setString(1, new String(arr2, 0, 16 * 1024 * 1024 - 21));
+      prep.setString(2, new String(arr2, 0, 30_000));
+      prep.execute();
+
+      prep.setString(1, new String(arr2, 0, 16 * 1024 * 1024 - 21));
+      prep.setString(2, new String(arr2, 0, 70_000));
+      prep.execute();
+      if (getMaxAllowedPacket() > 34 * 1024 * 1024) {
+        prep.setString(1, new String(arr2, 0, 16 * 1024 * 1024 - 21));
+        prep.setString(2, new String(arr2, 0, 17 * 1024 * 1024));
+        prep.execute();
+      }
+    }
+    ResultSet rs = stmt.executeQuery("SELECT t2 FROM multiPacketTest");
+    assertTrue(rs.next(), "expected rows");
+    assertEquals(new String(arr2, 0, 30_000), rs.getString(1));
+    rs.next();
+    assertEquals(new String(arr2, 0, 70_000), rs.getString(1));
+    rs.next();
+    if (getMaxAllowedPacket() > 34 * 1024 * 1024) {
+      assertEquals(new String(arr2, 0, 17 * 1024 * 1024), rs.getString(1));
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/MultiQueriesTest.java b/src/test/java/org/mariadb/jdbc/integration/MultiQueriesTest.java
new file mode 100644
index 0000000..66f0eeb
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/MultiQueriesTest.java
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+
+public class MultiQueriesTest extends Common {
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    after2();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE AllowMultiQueriesTest(id int not null primary key auto_increment, "
+            + "test varchar(10))");
+    stmt.execute("INSERT INTO AllowMultiQueriesTest(test) VALUES ('a'), ('b')");
+  }
+
+  @AfterAll
+  public static void after2() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE IF EXISTS AllowMultiQueriesTest");
+  }
+
+  @Test
+  public void allowMultiQueriesSingleTest() throws SQLException {
+    try (Connection connection = createCon("&allowMultiQueries=true")) {
+      try (Statement statement = connection.createStatement()) {
+        statement.execute("SELECT 1; SELECT 2; SELECT 3;");
+        int counter = 1;
+        do {
+          ResultSet resultSet = statement.getResultSet();
+          assertEquals(-1, statement.getUpdateCount());
+          assertTrue(resultSet.next());
+          assertEquals(counter++, resultSet.getInt(1));
+        } while (statement.getMoreResults());
+        assertEquals(4, counter);
+      }
+    }
+  }
+
+  @Test
+  public void checkMultiGeneratedKeys() throws SQLException {
+    try (Connection connection = createCon("&allowMultiQueries=true")) {
+      Statement stmt = connection.createStatement();
+      stmt.execute("SELECT 1; SET @TOTO=3; SELECT 2", java.sql.Statement.RETURN_GENERATED_KEYS);
+      ResultSet rs = stmt.getResultSet();
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt(1));
+      assertFalse(stmt.getMoreResults());
+      stmt.getGeneratedKeys();
+      assertTrue(stmt.getMoreResults());
+      rs = stmt.getResultSet();
+      assertTrue(rs.next());
+      assertEquals(2, rs.getInt(1));
+    }
+  }
+
+  @Test
+  public void allowMultiQueriesFetchTest() throws SQLException {
+    try (Connection connection = createCon("&allowMultiQueries=true")) {
+      try (Statement stmt = connection.createStatement()) {
+        stmt.setFetchSize(1);
+        stmt.execute("SELECT * from AllowMultiQueriesTest;SELECT * from AllowMultiQueriesTest;");
+        do {
+          ResultSet resultSet = stmt.getResultSet();
+          assertEquals(-1, stmt.getUpdateCount());
+          assertTrue(resultSet.next());
+          assertEquals("a", resultSet.getString(2));
+        } while (stmt.getMoreResults());
+
+        stmt.executeQuery(
+            "SELECT * from AllowMultiQueriesTest;SELECT * from AllowMultiQueriesTest;");
+        ResultSet rs = stmt.executeQuery("SELECT 1");
+        rs.next();
+        assertEquals(1, rs.getInt(1));
+      }
+      try (Statement statement = connection.createStatement()) {
+        statement.execute("SELECT 1");
+      }
+    }
+  }
+
+  @Test
+  public void quitWhileStreaming() throws SQLException {
+    // XPAND doesn't support DO command
+    Assumptions.assumeFalse(isXpand());
+
+    Connection connection = createCon("&allowMultiQueries=true");
+    Statement stmt = connection.createStatement();
+    stmt.setFetchSize(1);
+    stmt.executeQuery(
+        "DO 2;SELECT * from AllowMultiQueriesTest;SELECT * from AllowMultiQueriesTest; DO 1; SELECT"
+            + " 2");
+    connection.abort(Runnable::run);
+
+    connection = createCon("&allowMultiQueries=true");
+    stmt = connection.createStatement();
+    stmt.setFetchSize(1);
+    stmt.executeQuery("DO 2;DO 1;SELECT * from AllowMultiQueriesTest");
+    connection.abort(Runnable::run);
+  }
+
+  @Test
+  public void allowMultiQueriesFetchKeepTest() throws SQLException {
+    try (Connection connection = createCon("&allowMultiQueries=true")) {
+      try (Statement stmt = connection.createStatement()) {
+        stmt.setFetchSize(1);
+        stmt.execute("SELECT * from AllowMultiQueriesTest;SELECT 3;");
+        ResultSet rs1 = stmt.getResultSet();
+        assertTrue(stmt.getMoreResults(java.sql.Statement.KEEP_CURRENT_RESULT));
+        assertTrue(rs1.next());
+        assertEquals("a", rs1.getString(2));
+
+        ResultSet rs = stmt.getResultSet();
+        assertTrue(rs.next());
+        assertEquals(3, rs.getInt(1));
+      }
+    }
+  }
+
+  @Test
+  public void allowMultiQueriesFetchCloseTest() throws SQLException {
+    try (Connection connection = createCon("&allowMultiQueries=true")) {
+      try (Statement statement = connection.createStatement()) {
+        statement.setFetchSize(1);
+        statement.execute(
+            "SELECT * from AllowMultiQueriesTest;SELECT * from AllowMultiQueriesTest;SELECT 3;");
+        ResultSet rs1 = statement.getResultSet();
+        assertTrue(statement.getMoreResults(Statement.CLOSE_CURRENT_RESULT));
+        try {
+          rs1.next();
+          fail("Must have thrown exception, since closed");
+        } catch (SQLException sqle) {
+          assertTrue(sqle.getMessage().contains("Operation not permit on a closed resultSet"));
+        }
+
+        rs1 = statement.getResultSet();
+        assertTrue(statement.getMoreResults(java.sql.Statement.KEEP_CURRENT_RESULT));
+        assertTrue(rs1.next());
+        assertEquals("a", rs1.getString(2));
+
+        ResultSet rs = statement.getResultSet();
+        assertTrue(rs.next());
+        assertEquals(3, rs.getInt(1));
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ParameterMetaDataTest.java b/src/test/java/org/mariadb/jdbc/integration/ParameterMetaDataTest.java
new file mode 100644
index 0000000..3c5fd24
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ParameterMetaDataTest.java
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+
+public class ParameterMetaDataTest extends Common {
+
+  @AfterAll
+  public static void after2() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE IF EXISTS parameter_meta");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    after2();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE parameter_meta ("
+            + "id int not null primary key auto_increment, "
+            + "test varchar(20), "
+            + "t2 DECIMAL(10,3))");
+  }
+
+  @Test
+  public void parameterMetaDataTypeNotAvailable() throws Exception {
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts=false")) {
+      parameterMetaDataTypeNotAvailable(con);
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts")) {
+      parameterMetaDataTypeNotAvailable(con);
+    }
+  }
+
+  private void parameterMetaDataTypeNotAvailable(org.mariadb.jdbc.Connection con)
+      throws SQLException {
+    String query = "SELECT * FROM parameter_meta WHERE test = ? and id = ?";
+    try (PreparedStatement prepStmt = con.prepareStatement(query)) {
+      ParameterMetaData parameterMetaData = prepStmt.getParameterMetaData();
+      assertEquals(2, parameterMetaData.getParameterCount());
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> parameterMetaData.getParameterType(1),
+          "Getting parameter type metadata are not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> parameterMetaData.isNullable(-1), "Wrong index position");
+      Common.assertThrowsContains(
+          SQLException.class, () -> parameterMetaData.isNullable(3), "Wrong index position");
+    }
+  }
+
+  @Test
+  public void parameterMetaDataNotPreparable() throws Exception {
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts=false")) {
+      // statement that cannot be prepared
+      try (PreparedStatement pstmt =
+          con.prepareStatement("select  TMP.field1 from (select ? from dual) TMP")) {
+        ParameterMetaData meta = pstmt.getParameterMetaData();
+        assertEquals(1, meta.getParameterCount());
+        assertEquals(ParameterMetaData.parameterModeIn, meta.getParameterMode(1));
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getParameterTypeName(1),
+            "Unknown parameter metadata type name");
+        Common.assertThrowsContains(
+            SQLFeatureNotSupportedException.class,
+            () -> meta.getParameterClassName(1),
+            "Unknown parameter metadata class name");
+        Common.assertThrowsContains(
+            SQLFeatureNotSupportedException.class,
+            () -> meta.getParameterType(1),
+            "Getting parameter type metadata is not supported");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getPrecision(1),
+            "Unknown parameter metadata precision");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getScale(1),
+            "Unknown parameter metadata scale");
+
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getParameterMode(0),
+            "Wrong index position. Is 0 but must be in 1-1 range");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getParameterTypeName(0),
+            "Wrong index position. Is 0 but must be in 1-1 range");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getParameterMode(0),
+            "Wrong index position. Is 0 but must be in 1-1 range");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getParameterClassName(0),
+            "Wrong index position. Is 0 but must be in 1-1 range");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getParameterType(2),
+            "Wrong index position. Is 2 but must be in 1-1 range");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getPrecision(0),
+            "Wrong index position. Is 0 but must be in 1-1 range");
+        Common.assertThrowsContains(
+            SQLSyntaxErrorException.class,
+            () -> meta.getScale(0),
+            "Wrong index position. Is 0 but must be in 1-1 range");
+      }
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts")) {
+      // statement that cannot be prepared
+      try (PreparedStatement pstmt =
+          con.prepareStatement("select  TMP.field1 from (select ? from dual) TMP")) {
+        try {
+          pstmt.getParameterMetaData();
+          fail();
+        } catch (SQLSyntaxErrorException e) {
+          // eat
+        }
+      } catch (SQLSyntaxErrorException e) {
+        // eat
+      }
+    }
+  }
+
+  @Test
+  public void parameterMetaDataBasic() throws SQLException {
+    String query = "SELECT * FROM parameter_meta WHERE test = ? and id = ? and t2 = ?";
+    // Parameter type are not sent by server.
+    // See https://jira.mariadb.org/browse/CONJ-568 and https://jira.mariadb.org/browse/MDEV-15031
+    // so only basic info like parameter number are retrieved.
+    try (PreparedStatement prepStmt = sharedConnBinary.prepareStatement(query)) {
+      prepStmt.setString(1, "");
+      prepStmt.setInt(2, 1);
+      prepStmt.setInt(3, 1);
+      prepStmt.executeQuery();
+      ParameterMetaData meta = prepStmt.getParameterMetaData();
+      assertEquals(3, meta.getParameterCount());
+      if (!isMariaDBServer() && (minVersion(8, 0, 22) && !minVersion(8, 0, 30))) {
+        assertEquals(16383, meta.getPrecision(1));
+        assertEquals(31, meta.getScale(1));
+      } else {
+        // Xpand datatype as issue https://jira.mariadb.org/browse/XPT-279
+        if (!isXpand()) {
+          assertEquals(0, meta.getPrecision(1));
+          assertEquals(0, meta.getScale(1));
+        }
+      }
+
+      assertTrue(meta.isSigned(1));
+      assertEquals(ParameterMetaData.parameterNullable, meta.isNullable(1));
+      assertEquals(ParameterMetaData.parameterModeIn, meta.getParameterMode(1));
+
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> meta.getParameterType(1),
+          "Getting parameter type " + "metadata are not supported");
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> meta.getParameterClassName(1),
+          "Unknown parameter metadata class name");
+
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.getScale(20),
+          "Wrong index position. Is 20 but must be in 1-3 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.getPrecision(20),
+          "Wrong index position. Is 20 but must be in 1-3 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.isSigned(20),
+          "Wrong index position. Is 20 but must be in 1-3 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.isNullable(20),
+          "Wrong index position. Is 20 but must be in 1-3 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.getParameterTypeName(20),
+          "Wrong index position. Is 20 but must be in 1-3 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.getParameterMode(20),
+          "Wrong index position. Is 20 but must be in 1-3 range");
+
+      meta.unwrap(java.sql.ParameterMetaData.class);
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.unwrap(String.class),
+          "The receiver is not a wrapper for java.lang.String");
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/PoolDataSourceTest.java b/src/test/java/org/mariadb/jdbc/integration/PoolDataSourceTest.java
new file mode 100644
index 0000000..c014ec6
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/PoolDataSourceTest.java
@@ -0,0 +1,750 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.lang.management.ManagementFactory;
+import java.sql.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbPoolDataSource;
+import org.mariadb.jdbc.pool.PoolThreadFactory;
+import org.mariadb.jdbc.pool.Pools;
+
+public class PoolDataSourceTest extends Common {
+
+  /** Initialisation. */
+  @BeforeAll
+  public static void beforeClassDataSourceTest() throws SQLException {
+    drop();
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    boolean useOldNotation =
+        (!isMariaDBServer() || !minVersion(10, 2, 0))
+            && (isMariaDBServer() || !minVersion(8, 0, 0));
+    Statement stmt = sharedConn.createStatement();
+    if (useOldNotation) {
+      stmt.execute("CREATE USER IF NOT EXISTS 'poolUser'@'%'");
+      stmt.execute(
+          "GRANT SELECT ON "
+              + sharedConn.getCatalog()
+              + ".* TO 'poolUser'@'%' IDENTIFIED BY '!Passw0rd3Works'");
+    } else {
+      stmt.execute("CREATE USER IF NOT EXISTS 'poolUser'@'%' IDENTIFIED BY '!Passw0rd3Works'");
+      stmt.execute("GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO 'poolUser'@'%'");
+    }
+    stmt.execute(
+        "CREATE TABLE testResetRollback(id int not null primary key auto_increment, test"
+            + " varchar(20))");
+    stmt.execute("FLUSH TABLES");
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    try (Statement stmt = sharedConn.createStatement()) {
+      stmt.execute("DROP TABLE IF EXISTS testResetRollback");
+    }
+  }
+
+  @Test
+  public void basic() throws SQLException {
+    MariaDbPoolDataSource ds = new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=2");
+    testDs(ds);
+    ds.close();
+
+    ds = new MariaDbPoolDataSource();
+    ds.setUrl(mDefUrl + "&maxPoolSize=2");
+    testDs(ds);
+    ds.close();
+  }
+
+  private void testDs(MariaDbPoolDataSource ds) throws SQLException {
+    try (Connection con1 = ds.getConnection()) {
+      long threadId;
+      try (org.mariadb.jdbc.Connection con2 = (org.mariadb.jdbc.Connection) ds.getConnection()) {
+        threadId = con2.getThreadId();
+        ResultSet rs1 = con1.createStatement().executeQuery("SELECT 1");
+        ResultSet rs2 = con2.createStatement().executeQuery("SELECT 2");
+        while (rs1.next()) {
+          assertEquals(1, rs1.getInt(1));
+        }
+        while (rs2.next()) {
+          assertEquals(2, rs2.getInt(1));
+        }
+      }
+      try (org.mariadb.jdbc.Connection con2 = (org.mariadb.jdbc.Connection) ds.getConnection()) {
+        assertEquals(threadId, con2.getThreadId());
+      }
+    }
+
+    PooledConnection con1 = null;
+    PooledConnection con2 = null;
+    try {
+      con1 = ds.getPooledConnection();
+      con2 = ds.getPooledConnection();
+
+      ResultSet rs1 = con1.getConnection().createStatement().executeQuery("SELECT 1");
+      ResultSet rs2 = con2.getConnection().createStatement().executeQuery("SELECT 2");
+      while (rs1.next()) {
+        assertEquals(1, rs1.getInt(1));
+      }
+      while (rs2.next()) {
+        assertEquals(2, rs2.getInt(1));
+      }
+      long threadId = ((org.mariadb.jdbc.Connection) con2.getConnection()).getThreadId();
+      if (con2 != null) con2.getConnection().close();
+      con2 = ds.getPooledConnection();
+      assertEquals(threadId, ((org.mariadb.jdbc.Connection) con2.getConnection()).getThreadId());
+    } finally {
+      if (con1 != null) con1.getConnection().close();
+      if (con2 != null) con2.getConnection().close();
+    }
+
+    XAConnection conx1 = null;
+    XAConnection conx2 = null;
+    try {
+      conx1 = ds.getXAConnection();
+      conx2 = ds.getXAConnection();
+
+      ResultSet rs1 = conx1.getConnection().createStatement().executeQuery("SELECT 1");
+      ResultSet rs2 = conx2.getConnection().createStatement().executeQuery("SELECT 2");
+      while (rs1.next()) {
+        assertEquals(1, rs1.getInt(1));
+      }
+      while (rs2.next()) {
+        assertEquals(2, rs2.getInt(1));
+      }
+
+    } finally {
+      if (conx1 != null) con1.close();
+      if (conx2 != null) con2.close();
+    }
+  }
+
+  @Test
+  public void basic2() throws SQLException {
+    MariaDbPoolDataSource ds = new MariaDbPoolDataSource();
+    assertNull(ds.getUrl());
+    assertNull(ds.getUser());
+    assertEquals(30, ds.getLoginTimeout());
+    DriverManager.setLoginTimeout(40);
+    assertEquals(40, ds.getLoginTimeout());
+    DriverManager.setLoginTimeout(0);
+    ds.setLoginTimeout(50);
+    assertEquals(50, ds.getLoginTimeout());
+
+    assertThrows(SQLException.class, () -> ds.getConnection());
+    assertThrows(SQLException.class, () -> ds.getConnection("user", "password"));
+    assertThrows(SQLException.class, () -> ds.getPooledConnection());
+    assertThrows(SQLException.class, () -> ds.getPooledConnection("user", "password"));
+    assertThrows(SQLException.class, () -> ds.getXAConnection());
+    assertThrows(SQLException.class, () -> ds.getXAConnection("user", "password"));
+
+    ds.setUser("dd");
+    assertEquals("dd", ds.getUser());
+
+    ds.setPassword("pwd");
+    assertThrows(SQLException.class, () -> ds.getConnection());
+    assertThrows(SQLException.class, () -> ds.getPooledConnection());
+
+    assertThrows(SQLException.class, () -> ds.setUrl("jdbc:wrong://d"));
+
+    ds.setUrl("jdbc:mariadb://myhost:5500/db?someOption=val");
+    assertEquals(
+        "jdbc:mariadb://myhost:5500/db?user=dd&password=***&someOption=val&connectTimeout=50000",
+        ds.getUrl());
+    ds.close();
+  }
+
+  @Test
+  public void testDataSource() throws SQLException {
+    try (MariaDbPoolDataSource ds =
+        new MariaDbPoolDataSource(mDefUrl + "&allowPublicKeyRetrieval")) {
+      try (Connection connection = ds.getConnection()) {
+        assertEquals(connection.isValid(0), true);
+      }
+
+      try (Connection connection = ds.getConnection("poolUser", "!Passw0rd3Works")) {
+        assertEquals(connection.isValid(0), true);
+      }
+
+      PooledConnection poolCon = ds.getPooledConnection();
+      assertEquals(poolCon.getConnection().isValid(0), true);
+      poolCon.close();
+      poolCon = ds.getPooledConnection("poolUser", "!Passw0rd3Works");
+      assertEquals(poolCon.getConnection().isValid(0), true);
+      poolCon.close();
+    }
+  }
+
+  @Test
+  public void testResetDatabase() throws SQLException {
+    try (MariaDbPoolDataSource pool = new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1")) {
+      try (Connection connection = pool.getConnection()) {
+        Statement statement = connection.createStatement();
+        statement.execute("CREATE DATABASE IF NOT EXISTS testingReset");
+        connection.setCatalog("testingReset");
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        assertEquals(sharedConn.getCatalog(), connection.getCatalog());
+        Statement statement = connection.createStatement();
+        statement.execute("DROP DATABASE testingReset");
+      }
+    }
+  }
+
+  @Test
+  public void testResetSessionVariable() throws SQLException {
+    testResetSessionVariable(false);
+    if (isMariaDBServer() && minVersion(10, 2, 0)) {
+      testResetSessionVariable(true);
+    }
+  }
+
+  private void testResetSessionVariable(boolean useResetConnection) throws SQLException {
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            mDefUrl + "&maxPoolSize=1&useResetConnection=" + useResetConnection)) {
+
+      long nowMillis;
+      int initialWaitTimeout;
+
+      try (Connection connection = pool.getConnection()) {
+        Statement statement = connection.createStatement();
+
+        nowMillis = getNowTime(statement);
+        initialWaitTimeout = getWaitTimeout(statement);
+
+        statement.execute(
+            "SET @@timestamp=UNIX_TIMESTAMP('1970-10-01 01:00:00'), @@wait_timeout=2000");
+        long newNowMillis = getNowTime(statement);
+        int waitTimeout = getWaitTimeout(statement);
+
+        assertTrue(nowMillis - newNowMillis > 23_587_200_000L);
+        assertEquals(2_000, waitTimeout);
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        Statement statement = connection.createStatement();
+
+        long newNowMillis = getNowTime(statement);
+        int waitTimeout = getWaitTimeout(statement);
+
+        if (useResetConnection) {
+          assertTrue(nowMillis - newNowMillis < 10L);
+          assertEquals(initialWaitTimeout, waitTimeout);
+        } else {
+          assertTrue(nowMillis - newNowMillis > 23_587_200_000L);
+          assertEquals(2_000, waitTimeout);
+        }
+      }
+    }
+  }
+
+  private long getNowTime(Statement statement) throws SQLException {
+    ResultSet rs = statement.executeQuery("SELECT NOW()");
+    assertTrue(rs.next());
+    return rs.getTimestamp(1).getTime();
+  }
+
+  private int getWaitTimeout(Statement statement) throws SQLException {
+    ResultSet rs = statement.executeQuery("SELECT @@wait_timeout");
+    assertTrue(rs.next());
+    return rs.getInt(1);
+  }
+
+  @Test
+  public void testResetUserVariable() throws SQLException {
+    testResetUserVariable(false);
+    testResetUserVariable(false);
+    if (isMariaDBServer() && minVersion(10, 2, 0)) {
+      testResetUserVariable(true);
+      testResetUserVariable(true);
+    }
+  }
+
+  private void testResetUserVariable(boolean useResetConnection) throws SQLException {
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            mDefUrl
+                + "&maxPoolSize=1&useResetConnection="
+                + useResetConnection
+                + "&allowPublicKeyRetrieval")) {
+      try (Connection connection = pool.getConnection()) {
+        Statement statement = connection.createStatement();
+        assertNull(getUserVariableStr(statement));
+
+        statement.execute("SET @str = '123'");
+
+        assertEquals("123", getUserVariableStr(statement));
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        Statement statement = connection.createStatement();
+        if (useResetConnection) {
+          assertNull(getUserVariableStr(statement));
+        } else {
+          assertEquals("123", getUserVariableStr(statement));
+        }
+      }
+    }
+  }
+
+  private String getUserVariableStr(Statement statement) throws SQLException {
+    ResultSet rs = statement.executeQuery("SELECT @str");
+    assertTrue(rs.next());
+    return rs.getString(1);
+  }
+
+  @Test
+  public void testNetworkTimeout() throws SQLException {
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1&socketTimeout=10000")) {
+      try (Connection connection = pool.getConnection()) {
+        assertEquals(10_000, connection.getNetworkTimeout());
+        connection.setNetworkTimeout(null, 5_000);
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        assertEquals(10_000, connection.getNetworkTimeout());
+      }
+    }
+  }
+
+  @Test
+  public void testResetReadOnly() throws SQLException {
+    try (MariaDbPoolDataSource pool = new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1")) {
+      try (Connection connection = pool.getConnection()) {
+        assertFalse(connection.isReadOnly());
+        connection.setReadOnly(true);
+        assertTrue(connection.isReadOnly());
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        assertFalse(connection.isReadOnly());
+      }
+    }
+  }
+
+  @Test
+  public void testResetAutoCommit() throws SQLException {
+    try (MariaDbPoolDataSource pool = new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1")) {
+      try (Connection connection = pool.getConnection()) {
+        assertTrue(connection.getAutoCommit());
+        connection.setAutoCommit(false);
+        assertFalse(connection.getAutoCommit());
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        assertTrue(connection.getAutoCommit());
+      }
+    }
+  }
+
+  @Test
+  public void testResetAutoCommitOption() throws SQLException {
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1&autocommit=false&poolName=PoolTest")) {
+      assertTrue(pool.getPoolName().startsWith("PoolTest-"));
+      try (Connection connection = pool.getConnection()) {
+        assertFalse(connection.getAutoCommit());
+        connection.setAutoCommit(true);
+        assertTrue(connection.getAutoCommit());
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        assertFalse(connection.getAutoCommit());
+      }
+    }
+  }
+
+  @Test
+  public void testResetTransactionIsolation() throws SQLException {
+    try (MariaDbPoolDataSource pool = new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1")) {
+
+      try (Connection connection = pool.getConnection()) {
+        assertEquals(Connection.TRANSACTION_REPEATABLE_READ, connection.getTransactionIsolation());
+        connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+        assertEquals(Connection.TRANSACTION_SERIALIZABLE, connection.getTransactionIsolation());
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        assertEquals(Connection.TRANSACTION_REPEATABLE_READ, connection.getTransactionIsolation());
+      }
+    }
+  }
+
+  @Test
+  public void testJmx() throws Exception {
+    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+    ObjectName filter = new ObjectName("org.mariadb.jdbc.pool:type=PoolTestJmx-*");
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=5&minPoolSize=0&poolName=PoolTestJmx")) {
+      try (Connection connection = pool.getConnection()) {
+        connection.isValid(1);
+        Set<ObjectName> objectNames = server.queryNames(filter, null);
+        assertEquals(1, objectNames.size());
+        ObjectName name = objectNames.iterator().next();
+
+        MBeanInfo info = server.getMBeanInfo(name);
+        assertEquals(4, info.getAttributes().length);
+
+        checkJmxInfo(server, name, 1, 1, 0);
+
+        try (Connection connection2 = pool.getConnection()) {
+          connection2.isValid(1);
+          checkJmxInfo(server, name, 2, 2, 0);
+        }
+        checkJmxInfo(server, name, 1, 2, 1);
+      }
+    }
+  }
+
+  @Test
+  public void testNoMinConnection() throws Exception {
+    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+    ObjectName filter = new ObjectName("org.mariadb.jdbc.pool:type=testNoMinConnection-*");
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=5&poolName=testNoMinConnection")) {
+      try (Connection connection = pool.getConnection()) {
+        connection.isValid(1);
+        Set<ObjectName> objectNames = server.queryNames(filter, null);
+        assertEquals(1, objectNames.size());
+        ObjectName name = objectNames.iterator().next();
+
+        MBeanInfo info = server.getMBeanInfo(name);
+        assertEquals(4, info.getAttributes().length);
+
+        // wait to ensure pool has time to create 5 connections
+        try {
+          Thread.sleep(500);
+        } catch (InterruptedException interruptEx) {
+          // eat
+        }
+
+        checkJmxInfo(server, name, 1, 5, 4);
+
+        try (Connection connection2 = pool.getConnection()) {
+          connection2.isValid(1);
+          checkJmxInfo(server, name, 2, 5, 3);
+        }
+        checkJmxInfo(server, name, 1, 5, 4);
+      }
+    }
+  }
+
+  @Test
+  public void testIdleTimeout() throws Throwable {
+    // appveyor is so slow wait time are not relevant.
+    Assumptions.assumeTrue(System.getenv("APPVEYOR_BUILD_WORKER_IMAGE") == null);
+
+    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+    ObjectName filter = new ObjectName("org.mariadb.jdbc.pool:type=testIdleTimeout-*");
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            mDefUrl
+                + "&maxPoolSize=5&minPoolSize=3&poolName=testIdleTimeout&testMinRemovalDelay=50&maxIdleTime=100")) {
+      // wait to ensure pool has time to create 3 connections
+      Thread.sleep(1_000);
+
+      Set<ObjectName> objectNames = server.queryNames(filter, null);
+      ObjectName name = objectNames.iterator().next();
+      checkJmxInfo(server, name, 0, 3, 3);
+
+      List<Long> initialThreadIds = pool.testGetConnectionIdleThreadIds();
+      Thread.sleep(200);
+
+      // must still have 3 connections, but must be other ones
+      checkJmxInfo(server, name, 0, 3, 3);
+    }
+  }
+
+  @Test
+  public void testMinConnection() throws Throwable {
+    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+    ObjectName filter = new ObjectName("org.mariadb.jdbc.pool:type=testMinConnection-*");
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            mDefUrl
+                + "&maxPoolSize=5&minPoolSize=3&poolName=testMinConnection&testMinRemovalDelay=30&maxIdleTime=100")) {
+      try (Connection connection = pool.getConnection()) {
+        connection.isValid(1);
+        Set<ObjectName> objectNames = server.queryNames(filter, null);
+        assertEquals(1, objectNames.size());
+        ObjectName name = objectNames.iterator().next();
+
+        MBeanInfo info = server.getMBeanInfo(name);
+        assertEquals(4, info.getAttributes().length);
+
+        // to ensure pool has time to create minimal connection number
+        Thread.sleep(200);
+
+        checkJmxInfo(server, name, 1, 3, 2);
+
+        try (Connection connection2 = pool.getConnection()) {
+          connection2.isValid(1);
+          checkJmxInfo(server, name, 2, 3, 1);
+        }
+        checkJmxInfo(server, name, 1, 3, 2);
+      }
+    }
+  }
+
+  private void checkJmxInfo(
+      MBeanServer server,
+      ObjectName name,
+      long expectedActive,
+      long expectedTotal,
+      long expectedIdle)
+      throws Exception {
+
+    assertEquals(
+        expectedActive, ((Long) server.getAttribute(name, "ActiveConnections")).longValue());
+    assertEquals(expectedTotal, ((Long) server.getAttribute(name, "TotalConnections")).longValue());
+    assertEquals(expectedIdle, ((Long) server.getAttribute(name, "IdleConnections")).longValue());
+    assertEquals(0, ((Long) server.getAttribute(name, "ConnectionRequests")).longValue());
+  }
+
+  @Test
+  public void testJmxDisable() throws Exception {
+    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+    ObjectName filter = new ObjectName("org.mariadb.jdbc.pool:type=PoolTest-*");
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            mDefUrl + "&maxPoolSize=2&registerJmxPool=false&poolName=PoolTest")) {
+      try (Connection connection = pool.getConnection()) {
+        connection.isValid(1);
+        Set<ObjectName> objectNames = server.queryNames(filter, null);
+        assertEquals(0, objectNames.size());
+      }
+    }
+  }
+
+  @Test
+  public void testResetRollback() throws SQLException {
+    sharedConn.createStatement().execute("FLUSH TABLES");
+    try (MariaDbPoolDataSource pool = new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1")) {
+      try (Connection connection = pool.getConnection()) {
+        Statement stmt = connection.createStatement();
+        stmt.executeUpdate("INSERT INTO testResetRollback (test) VALUES ('heja')");
+        connection.setAutoCommit(false);
+        stmt.executeUpdate("INSERT INTO testResetRollback (test) VALUES ('japp')");
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        Statement stmt = connection.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT count(*) FROM testResetRollback");
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+      }
+    }
+  }
+
+  @Test
+  public void ensureUsingPool() throws Exception {
+    ThreadPoolExecutor connectionAppender =
+        new ThreadPoolExecutor(
+            50,
+            5000,
+            10,
+            TimeUnit.SECONDS,
+            new LinkedBlockingQueue<>(5000),
+            new PoolThreadFactory("testPool"));
+
+    final long start = System.currentTimeMillis();
+    Set<Integer> threadIds = new HashSet<>();
+    for (int i = 0; i < 500; i++) {
+      connectionAppender.execute(
+          () -> {
+            try (Connection connection =
+                DriverManager.getConnection(
+                    mDefUrl + "&pool&staticGlobal&poolName=PoolEnsureUsingPool&log=true")) {
+              Statement stmt = connection.createStatement();
+              ResultSet rs = stmt.executeQuery("SELECT CONNECTION_ID()");
+              rs.next();
+              Integer connectionId = rs.getInt(1);
+              threadIds.add(connectionId);
+              stmt.execute("SELECT 1");
+
+            } catch (SQLException e) {
+              e.printStackTrace();
+            }
+          });
+    }
+    connectionAppender.shutdown();
+    connectionAppender.awaitTermination(30, TimeUnit.SECONDS);
+    assertTrue(threadIds.size() <= 9, "connection ids must be less than 9 : " + threadIds.size());
+    Pools.close("PoolTest");
+  }
+
+  @Test
+  public void ensureClosed() throws Throwable {
+    Thread.sleep(500); // ensure that previous close are effective
+    int initialConnection = getCurrentConnections();
+    Assumptions.assumeFalse(initialConnection == -1);
+
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=10&minPoolSize=1")) {
+
+      try (Connection connection = pool.getConnection()) {
+        connection.isValid(10_000);
+      }
+
+      assertTrue(getCurrentConnections() > initialConnection);
+
+      // reuse IdleConnection
+      try (Connection connection = pool.getConnection()) {
+        connection.isValid(10_000);
+      }
+
+      Thread.sleep(500);
+      assertTrue(getCurrentConnections() > initialConnection);
+    }
+    Thread.sleep(2000); // ensure that previous close are effective
+    assertEquals(initialConnection, getCurrentConnections());
+  }
+
+  @Test
+  public void wrongUrlHandling() throws SQLException {
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            "jdbc:mariadb://unknownHost/db?user=wrong&maxPoolSize=10&connectTimeout=500")) {
+      long start = System.currentTimeMillis();
+      try {
+        pool.getConnection();
+        fail();
+      } catch (SQLException sqle) {
+        // ensure more time for windows
+        assertTrue(
+            (System.currentTimeMillis() - start) >= 500
+                && (System.currentTimeMillis() - start) < 850,
+            "timeout does not correspond to option. Elapsed time:"
+                + (System.currentTimeMillis() - start));
+        assertTrue(
+            sqle.getMessage()
+                .contains(
+                    "No connection available within the specified time (option 'connectTimeout':"
+                        + " 500 ms)"));
+      }
+    }
+  }
+
+  @Test
+  public void testPrepareReset() throws SQLException {
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            mDefUrl + "&maxPoolSize=1&useServerPrepStmts=true&useResetConnection")) {
+      try (Connection connection = pool.getConnection()) {
+        PreparedStatement preparedStatement = connection.prepareStatement("SELECT ?");
+        preparedStatement.setString(1, "1");
+        preparedStatement.execute();
+      }
+
+      try (Connection connection = pool.getConnection()) {
+        // must re-prepare
+        PreparedStatement preparedStatement = connection.prepareStatement("SELECT ?");
+        preparedStatement.setString(1, "1");
+        preparedStatement.execute();
+      }
+    }
+  }
+
+  /**
+   * List current connections to server.
+   *
+   * @return number of thread connected.
+   */
+  public static int getCurrentConnections() {
+    try {
+      Statement stmt = sharedConn.createStatement();
+      ResultSet rs = stmt.executeQuery("show status where `variable_name` = 'Threads_connected'");
+      if (rs.next()) {
+        System.out.println("threads : " + rs.getInt(2));
+        return rs.getInt(2);
+      }
+      return -1;
+    } catch (SQLException e) {
+      return -1;
+    }
+  }
+
+  @Test
+  public void poolWithUser() throws SQLException {
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(
+            mDefUrl + "&maxPoolSize=1&poolName=myPool&allowPublicKeyRetrieval")) {
+      long threadId = 0;
+      try (Connection conn = pool.getConnection()) {
+        conn.isValid(1);
+        threadId = ((org.mariadb.jdbc.Connection) conn).getThreadId();
+      }
+
+      try (Connection conn = pool.getConnection(user, password)) {
+        conn.isValid(1);
+        assertEquals(threadId, ((org.mariadb.jdbc.Connection) conn).getThreadId());
+      }
+      try (Connection conn = pool.getConnection("poolUser", "!Passw0rd3Works")) {
+        conn.isValid(1);
+        assertNotEquals(threadId, ((org.mariadb.jdbc.Connection) conn).getThreadId());
+      }
+    }
+  }
+
+  @Test
+  public void various() throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> new MariaDbPoolDataSource("jdbc:notMariadb"),
+        "Wrong mariaDB url");
+    try (MariaDbPoolDataSource pool =
+        new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1&poolName=myPool&connectTimeout=2000")) {
+      assertNotNull(pool.unwrap(org.mariadb.jdbc.MariaDbPoolDataSource.class));
+      assertNotNull(pool.unwrap(ConnectionPoolDataSource.class));
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> pool.unwrap(String.class),
+          "Datasource is not a wrapper for java.lang.String");
+      assertTrue(pool.isWrapperFor(org.mariadb.jdbc.MariaDbPoolDataSource.class));
+      assertTrue(pool.isWrapperFor(ConnectionPoolDataSource.class));
+      assertFalse(pool.isWrapperFor(String.class));
+      pool.setLogWriter(null);
+      assertNull(pool.getLogWriter());
+      assertNull(pool.getParentLogger());
+      assertEquals(2, pool.getLoginTimeout());
+      pool.setLoginTimeout(4);
+      assertEquals(4, pool.getLoginTimeout());
+    }
+  }
+
+  @Test
+  public void pools() throws SQLException {
+    // ensure all are closed
+    Pools.close();
+    Pools.close(null);
+    new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1&poolName=myPool");
+    Pools.close("myPool");
+    new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1&poolName=myPool");
+    Pools.close();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/PooledConnectionTest.java b/src/test/java/org/mariadb/jdbc/integration/PooledConnectionTest.java
new file mode 100644
index 0000000..a5da9c4
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/PooledConnectionTest.java
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.*;
+import java.sql.Connection;
+import java.sql.Statement;
+import javax.sql.*;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.*;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.integration.tools.TcpProxy;
+import org.mariadb.jdbc.pool.MariaDbInnerPoolConnection;
+import org.mariadb.jdbc.pool.Pool;
+import org.mariadb.jdbc.pool.Pools;
+
+public class PooledConnectionTest extends Common {
+
+  @Test
+  public void testPooledConnectionClosed() throws Exception {
+    ConnectionPoolDataSource ds = new MariaDbDataSource(mDefUrl);
+    PooledConnection pc = ds.getPooledConnection();
+    Connection connection = pc.getConnection();
+    MyEventListener listener = new MyEventListener();
+    pc.addConnectionEventListener(listener);
+    pc.addStatementEventListener(listener);
+    pc.close();
+    assertTrue(listener.closed);
+    assertThrows(SQLException.class, () -> connection.createStatement().execute("select 1"));
+    pc.removeConnectionEventListener(listener);
+    pc.removeStatementEventListener(listener);
+  }
+
+  @Test
+  public void testPoolWait() throws Exception {
+    try (MariaDbPoolDataSource ds =
+        new MariaDbPoolDataSource(
+            mDefUrl + "&sessionVariables=wait_timeout=1&maxIdleTime=2&testMinRemovalDelay=2")) {
+      Thread.sleep(4000);
+      PooledConnection pc = ds.getPooledConnection();
+      pc.getConnection().isValid(1);
+      pc.close();
+    }
+  }
+
+  @Test
+  public void testPoolWaitWithValidation() throws Exception {
+    try (MariaDbPoolDataSource ds = new MariaDbPoolDataSource(mDefUrl + "&poolValidMinDelay=1")) {
+      Thread.sleep(100);
+      PooledConnection pc = ds.getPooledConnection();
+      pc.getConnection().isValid(1);
+      pc.close();
+    }
+  }
+
+  @Test
+  public void testPoolFailover() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+
+    Configuration conf = Configuration.parse(mDefUrl);
+    HostAddress hostAddress = conf.addresses().get(0);
+    try {
+      proxy = new TcpProxy(hostAddress.host, hostAddress.port);
+    } catch (IOException i) {
+      throw new SQLException("proxy error", i);
+    }
+
+    String url = mDefUrl.replaceAll("//([^/]*)/", "//localhost:" + proxy.getLocalPort() + "/");
+    if (conf.sslMode() == SslMode.VERIFY_FULL) {
+      url = url.replaceAll("sslMode=verify-full", "sslMode=verify-ca");
+    }
+
+    try (MariaDbPoolDataSource ds =
+        new MariaDbPoolDataSource(url + "&poolValidMinDelay=1&connectTimeout=10&maxPoolSize=1")) {
+
+      PooledConnection pc = ds.getPooledConnection();
+      pc.getConnection().isValid(1);
+      pc.close();
+      Thread.sleep(200);
+      proxy.stop();
+      Common.assertThrowsContains(
+          SQLException.class,
+          ds::getPooledConnection,
+          "No connection available within the specified time");
+    }
+  }
+
+  @Test
+  public void testPoolKillConnection() throws Exception {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !"galera".equals(System.getenv("srv"))
+            && !isXpand());
+
+    File tempFile = File.createTempFile("log", ".tmp");
+    //
+    //    Logger logger = (Logger) LoggerFactory.getLogger("org.mariadb.jdbc");
+    //    Level initialLevel = logger.getLevel();
+    //    logger.setLevel(Level.TRACE);
+    //    logger.setAdditive(false);
+    //    logger.detachAndStopAllAppenders();
+    //
+    //    LoggerContext context = new LoggerContext();
+    //    FileAppender<ILoggingEvent> fa = new FileAppender<>();
+    //    fa.setName("FILE");
+    //    fa.setImmediateFlush(true);
+    //    PatternLayoutEncoder pa = new PatternLayoutEncoder();
+    //    pa.setPattern("%r %5p %c [%t] - %m%n");
+    //    pa.setContext(context);
+    //    pa.start();
+    //    fa.setEncoder(pa);
+    //
+    //    fa.setFile(tempFile.getPath());
+    //    fa.setAppend(true);
+    //    fa.setContext(context);
+    //    fa.start();
+    //
+    //    logger.addAppender(fa);
+
+    try (MariaDbPoolDataSource ds =
+        new MariaDbPoolDataSource(mDefUrl + "&maxPoolSize=1&allowPublicKeyRetrieval")) {
+      Thread.sleep(100);
+      MariaDbInnerPoolConnection pc = (MariaDbInnerPoolConnection) ds.getPooledConnection();
+      org.mariadb.jdbc.Connection conn = pc.getConnection();
+      long threadId = conn.getThreadId();
+      try {
+        conn.createStatement().execute("KILL " + threadId);
+      } catch (SQLException e) {
+        // eat "Connection was killed" message
+      }
+      pc.close();
+      pc = (MariaDbInnerPoolConnection) ds.getPooledConnection();
+      conn = pc.getConnection();
+      assertNotEquals(threadId, conn.getThreadId());
+      pc.close();
+    } finally {
+
+      //      String contents = new String(Files.readAllBytes(Paths.get(tempFile.getPath())));
+      //      assertTrue(
+      //          contents.contains(
+      //              "removed from pool MariaDB-pool due to error during reset (total:0, active:0,
+      // pending:0)"),
+      //          contents);
+      //      assertTrue(contents.contains("pool MariaDB-pool new physical connection created"),
+      // contents);
+      //
+      //      assertTrue(
+      //          contents.contains("closing pool MariaDB-pool (total:1, active:0, pending:0)"),
+      // contents);
+      //      logger.setLevel(initialLevel);
+      //      logger.detachAppender(fa);
+    }
+  }
+
+  @Test
+  public void testPooledConnectionException() throws Exception {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !"galera".equals(System.getenv("srv"))
+            && !isXpand());
+
+    ConnectionPoolDataSource ds = new MariaDbDataSource(mDefUrl);
+    PooledConnection pc = null;
+    try {
+      pc = ds.getPooledConnection();
+      MyEventListener listener = new MyEventListener();
+      pc.addConnectionEventListener(listener);
+      Connection connection = pc.getConnection();
+
+      /* Ask server to abort the connection */
+      try {
+        connection.createStatement().execute("KILL CONNECTION_ID()");
+      } catch (Exception e) {
+        /* exception is expected here, server sends query aborted */
+      }
+
+      /* Try to read  after server side closed the connection */
+      assertThrows(SQLException.class, () -> connection.createStatement().execute("SELECT 1"));
+    } finally {
+      if (pc != null) {
+        pc.close();
+      }
+    }
+  }
+
+  @Test
+  public void testPooledConnectionException2() throws Exception {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try (Pool pool = Pools.retrievePool(Configuration.parse(mDefUrl + "&maxPoolSize=2"))) {
+      MariaDbInnerPoolConnection pooledConnection = pool.getPoolConnection();
+      org.mariadb.jdbc.Connection con = pooledConnection.getConnection();
+      con.setAutoCommit(false);
+      con.createStatement().execute("START TRANSACTION ");
+
+      Connection con2 = pool.getPoolConnection().getConnection();
+      con2.createStatement().execute("KILL " + con.getThreadId());
+      con2.close();
+      Thread.sleep(10);
+      assertThrows(SQLException.class, con::commit);
+      pooledConnection.close();
+    }
+  }
+
+  @Test
+  public void testPooledConnectionStatementError() throws Exception {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("DROP USER 'dsUser'");
+    } catch (SQLException e) {
+      // eat
+    }
+
+    if (minVersion(8, 0, 0)) {
+      if (isMariaDBServer()) {
+        stmt.execute("CREATE USER 'dsUser'@'%' IDENTIFIED BY 'MySup8%rPassw@ord'");
+        stmt.execute("GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO 'dsUser'@'%'");
+      } else {
+        stmt.execute(
+            "CREATE USER 'dsUser'@'%' IDENTIFIED WITH mysql_native_password BY"
+                + " 'MySup8%rPassw@ord'");
+        stmt.execute("GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO 'dsUser'@'%'");
+      }
+    } else {
+      stmt.execute("CREATE USER 'dsUser'@'%'");
+      stmt.execute(
+          "GRANT SELECT ON "
+              + sharedConn.getCatalog()
+              + ".* TO 'dsUser'@'%' IDENTIFIED BY 'MySup8%rPassw@ord'");
+    }
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES");
+
+    ConnectionPoolDataSource ds = new MariaDbDataSource(mDefUrl);
+    PooledConnection pc = ds.getPooledConnection("dsUser", "MySup8%rPassw@ord");
+    MyEventListener listener = new MyEventListener();
+    pc.addStatementEventListener(listener);
+    Connection connection = pc.getConnection();
+    try (PreparedStatement ps = connection.prepareStatement("SELECT ?")) {
+      ps.execute();
+      fail("should never get there");
+    } catch (Exception e) {
+      assertTrue(listener.statementErrorOccurred);
+    }
+    assertTrue(listener.statementClosed);
+    pc.close();
+  }
+
+  public static class MyEventListener implements ConnectionEventListener, StatementEventListener {
+
+    public SQLException sqlException;
+    public boolean closed;
+    public boolean connectionErrorOccurred;
+    public boolean statementClosed;
+    public boolean statementErrorOccurred;
+
+    /** MyEventListener initialisation. */
+    public MyEventListener() {
+      sqlException = null;
+      closed = false;
+      connectionErrorOccurred = false;
+    }
+
+    public void connectionClosed(ConnectionEvent event) {
+      sqlException = event.getSQLException();
+      closed = true;
+    }
+
+    public void connectionErrorOccurred(ConnectionEvent event) {
+      sqlException = event.getSQLException();
+      connectionErrorOccurred = true;
+    }
+
+    public void statementClosed(StatementEvent event) {
+      statementClosed = true;
+    }
+
+    public void statementErrorOccurred(StatementEvent event) {
+      sqlException = event.getSQLException();
+      statementErrorOccurred = true;
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/PreparedStatementMetadataTest.java b/src/test/java/org/mariadb/jdbc/integration/PreparedStatementMetadataTest.java
new file mode 100644
index 0000000..acd4942
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/PreparedStatementMetadataTest.java
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+
+public class PreparedStatementMetadataTest extends Common {
+
+  @Test
+  public void execute() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      execute(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      execute(con);
+    }
+  }
+
+  private void execute(Connection conn) throws SQLException {
+    Statement stmt = conn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS prepareMeta");
+    stmt.execute("CREATE TABLE prepareMeta(id int, val varchar(256))");
+    try (PreparedStatement prep = conn.prepareStatement("SELECT * FROM prepareMeta")) {
+      ResultSetMetaData meta = prep.getMetaData();
+      assertEquals(2, meta.getColumnCount());
+      meta = prep.getMetaData();
+      assertEquals(2, meta.getColumnCount());
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/PreparedStatementParametersTest.java b/src/test/java/org/mariadb/jdbc/integration/PreparedStatementParametersTest.java
new file mode 100644
index 0000000..f723f25
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/PreparedStatementParametersTest.java
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+
+public class PreparedStatementParametersTest extends Common {
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE bigTest (t1 int not null primary key auto_increment, t2 LONGTEXT)");
+    stmt.execute("CREATE TABLE prepareParam (t1 BLOB(20))");
+    stmt.execute("CREATE TABLE prepareParam2 (t1 BIGINT)");
+    stmt.execute("CREATE TABLE prepareParam3 (t1 DOUBLE)");
+    stmt.execute(
+        "CREATE TABLE prepareParam4 (t1 VARCHAR(30)) "
+            + "CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+    stmt.execute("CREATE TABLE prepareParam5 (t1 TIMESTAMP(6))");
+    stmt.execute("CREATE TABLE prepareParam6 (t1 BIGINT)");
+    stmt.execute("CREATE TABLE prepareParam7 (t1 TIME(6))");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS bigTest");
+    stmt.execute("DROP TABLE IF EXISTS prepareParam");
+    stmt.execute("DROP TABLE IF EXISTS prepareParam2");
+    stmt.execute("DROP TABLE IF EXISTS prepareParam3");
+    stmt.execute("DROP TABLE IF EXISTS prepareParam4");
+    stmt.execute("DROP TABLE IF EXISTS prepareParam5");
+    stmt.execute("DROP TABLE IF EXISTS prepareParam6");
+    stmt.execute("DROP TABLE IF EXISTS prepareParam7");
+  }
+
+  @Test
+  public void validateParameters() throws Exception {
+    // error crashing maxscale 6.1.x
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.1.")
+            && !"skysql-ha".equals(System.getenv("srv")));
+    validateParameters(sharedConn);
+    validateParameters(sharedConnBinary);
+  }
+
+  public void validateParameters(Connection con) throws Exception {
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO prepareParam6 VALUES (?)")) {
+      try {
+        prep.execute();
+        fail();
+      } catch (SQLException sqle) {
+        // eat
+      }
+    }
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO prepareParam6 VALUES (?)")) {
+      prep.setInt(1, 1);
+      prep.execute();
+      prep.clearParameters();
+      Common.assertThrowsContains(
+          SQLTransientConnectionException.class,
+          prep::execute,
+          "Parameter at position 1 is not set");
+    }
+  }
+
+  @Test
+  public void checkParameters() throws Exception {
+    checkParameters(sharedConn, true);
+    checkParameters(sharedConnBinary, false);
+  }
+
+  @SuppressWarnings("deprecation")
+  public void checkParameters(org.mariadb.jdbc.Connection con, boolean text) throws Exception {
+    Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+    checkSendBlob(
+        ps -> ps.setBlob(1, new MariaDbBlob("0123".getBytes(), 1, 2)),
+        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
+        con);
+    checkSendBlob(
+        ps -> ps.setBlob(1, new MariaDbBlob("0123".getBytes(), 1, 2).getBinaryStream()),
+        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
+        con);
+    checkSendBlob(
+        ps -> ps.setBlob(1, new MariaDbBlob("01234".getBytes(), 1, 3).getBinaryStream(), 2),
+        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
+        con);
+    checkSendBlob(
+        ps -> ps.setBlob(1, new MariaDbBlob("01234".getBytes(), 1, 3).getBinaryStream(), 2L),
+        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
+        con);
+    checkSendBlob(ps -> ps.setNull(1, Types.VARBINARY), rs -> assertNull(rs.getObject(1)), con);
+    checkSendBlob(
+        ps -> ps.setNull(1, Types.VARBINARY, String.class.getName()),
+        rs -> assertNull(rs.getObject(1)),
+        con);
+    checkSendLong(ps -> ps.setBoolean(1, true), rs -> assertTrue(rs.getBoolean(1)), con);
+    checkSendLong(ps -> ps.setBoolean(1, false), rs -> assertFalse(rs.getBoolean(1)), con);
+    checkSendLong(
+        ps -> ps.setByte(1, (byte) 0x58), rs -> assertEquals((byte) 0x58, rs.getByte(1)), con);
+    checkSendLong(
+        ps -> ps.setShort(1, (short) 127), rs -> assertEquals((short) 127, rs.getShort(1)), con);
+    checkSendLong(ps -> ps.setInt(1, -555), rs -> assertEquals(-555, rs.getInt(1)), con);
+    checkSendLong(ps -> ps.setLong(1, -999L), rs -> assertEquals(-999L, rs.getLong(1)), con);
+    checkSendDouble(
+        ps -> ps.setFloat(1, -56.59F), rs -> assertEquals(-56.59F, rs.getFloat(1), 0.01F), con);
+    checkSendDouble(
+        ps -> ps.setDouble(1, -56.59D), rs -> assertEquals(-56.59D, rs.getDouble(1), 0.01D), con);
+    checkSendDouble(
+        ps -> ps.setBigDecimal(1, new BigDecimal("-156.59")),
+        rs ->
+            assertEquals(
+                new BigDecimal("-156.59"), rs.getBigDecimal(1).setScale(2, RoundingMode.HALF_DOWN)),
+        con);
+    checkSendString(
+        ps -> ps.setString(1, "你好(hello in Chinese)"),
+        rs -> assertEquals("你好(hello in Chinese)", rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNString(1, "你好(hello in Chinese)"),
+        rs -> assertEquals("你好(hello in Chinese)", rs.getNString(1)),
+        con);
+    checkSendBlob(
+        ps -> ps.setBytes(1, "01234".getBytes()),
+        rs -> assertArrayEquals("01234".getBytes(), rs.getBytes(1)),
+        con);
+    checkSendTimestamp(
+        ps -> ps.setDate(1, Date.valueOf("2010-05-25")),
+        rs -> assertEquals(Date.valueOf("2010-05-25"), rs.getDate(1)),
+        con);
+    boolean minus = TimeZone.getDefault().getOffset(System.currentTimeMillis()) > 0;
+    checkSendTimestamp(
+        ps -> ps.setDate(1, Date.valueOf("2010-01-12"), utcCal),
+        rs ->
+            assertEquals(minus ? 1263164400000L : 1263254400000L, rs.getDate(1, utcCal).getTime()),
+        con);
+    checkSendTimestamp(
+        ps -> ps.setDate(1, Date.valueOf("2010-01-12"), utcCal),
+        rs -> assertEquals(minus ? "2010-01-11" : "2010-01-12", rs.getDate(1, utcCal).toString()),
+        con);
+    checkSendTimestamp(
+        ps -> ps.setDate(1, Date.valueOf("2010-05-25")),
+        rs -> assertEquals(Date.valueOf("2010-05-25").getTime(), rs.getDate(1).getTime()),
+        con);
+    if (isXpand()) {
+      // skip due to error https://jira.mariadb.org/browse/XPT-265
+    } else {
+      if (text) {
+        Common.assertThrowsContains(
+            SQLException.class,
+            () ->
+                checkSendTimestamp(
+                    ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime() + 123)),
+                    rs ->
+                        assertEquals(
+                            Time.valueOf("18:16:01").getTime() + 123, rs.getTime(1).getTime()),
+                    con),
+            "Incorrect datetime value: '18:16:01.123'");
+      } else {
+        checkSendTimestamp(
+            ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime() + 123)),
+            rs -> assertEquals(Time.valueOf("18:16:01").getTime() + 123, rs.getTime(1).getTime()),
+            con);
+      }
+    }
+
+    checkSendTimestamp(
+        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987")),
+        rs ->
+            assertEquals(
+                Timestamp.valueOf("2010-05-25 18:16:01.987").getTime(),
+                rs.getTimestamp(1).getTime()),
+        con);
+    checkSendTimestamp(
+        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987")),
+        rs -> assertEquals("2010-05-25 18:16:01.987", rs.getTimestamp(1).toString()),
+        con);
+    checkSendTimestamp(
+        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987"), utcCal),
+        rs ->
+            assertEquals(
+                Timestamp.valueOf("2010-05-25 18:16:01.987").getTime(),
+                rs.getTimestamp(1, utcCal).getTime()),
+        con);
+
+    checkSendTimestamp(
+        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987"), utcCal),
+        rs ->
+            assertEquals(
+                Timestamp.valueOf("2010-05-25 18:16:01.987").getTime()
+                    - TimeZone.getDefault().getOffset(1, 2010, 5, 25, 1, 987),
+                rs.getTimestamp(1).getTime()),
+        con);
+    checkSendString(
+        ps -> ps.setAsciiStream(1, new ByteArrayInputStream("abcdef".getBytes())),
+        rs -> assertEquals("abcdef", rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setAsciiStream(1, new ByteArrayInputStream("abcdef".getBytes()), 5),
+        rs -> assertEquals("abcde", rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setAsciiStream(1, new ByteArrayInputStream("abcdef".getBytes()), 5L),
+        rs -> assertEquals("abcde", rs.getString(1)),
+        con);
+    final String unicodeString =
+        ""
+            + "\uD83D\uDE0E" // 😎 unicode 6 smiling face with sunglasses
+            + "\uD83C\uDF36" // 🌶 unicode 7 hot pepper
+            + "\uD83C\uDFA4" // 🎤 unicode 8 no microphones
+            + "\uD83E\uDD42 "; // 🥂 unicode 9 clinking glasses
+    final byte[] unicodeBytes = unicodeString.getBytes(StandardCharsets.UTF_8);
+    checkSendString(
+        ps -> ps.setUnicodeStream(1, new ByteArrayInputStream(unicodeBytes), 16),
+        rs ->
+            assertEquals(
+                unicodeString.substring(0, 8),
+                rs.getString(1),
+                "expected " + unicodeString.substring(0, 8) + " but is " + rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setBinaryStream(1, new ByteArrayInputStream(unicodeBytes)),
+        rs -> assertEquals(unicodeString, rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setBinaryStream(1, new ByteArrayInputStream(unicodeBytes), 16),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setBinaryStream(1, new ByteArrayInputStream(unicodeBytes), 16L),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setCharacterStream(1, new StringReader(unicodeString)),
+        rs -> assertEquals(unicodeString, rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setCharacterStream(1, new StringReader(unicodeString), 8),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setCharacterStream(1, new StringReader(unicodeString), 8L),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNCharacterStream(1, new StringReader(unicodeString)),
+        rs -> assertEquals(unicodeString, rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNCharacterStream(1, new StringReader(unicodeString), 8),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNCharacterStream(1, new StringReader(unicodeString), 8L),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setClob(1, new MariaDbClob(unicodeBytes, 0, 16)),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setClob(1, new StringReader(unicodeString)),
+        rs -> assertEquals(unicodeString, rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setClob(1, new StringReader(unicodeString), 8),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setClob(1, new StringReader(unicodeString), 8L),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNClob(1, new MariaDbClob(unicodeBytes, 0, 16)),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNClob(1, new StringReader(unicodeString)),
+        rs -> assertEquals(unicodeString, rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNClob(1, new StringReader(unicodeString), 8),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setNClob(1, new StringReader(unicodeString), 8L),
+        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
+        con);
+    checkSendString(
+        ps -> ps.setURL(1, new URL("https://www.someUrl.com")),
+        rs -> assertEquals("https://www.someUrl.com", rs.getString(1)),
+        con);
+    // TODO SET OBJECT
+  }
+
+  @Test
+  public void checkTimeParameters() throws Exception {
+    checkTimeParameters(sharedConn);
+    checkTimeParameters(sharedConnBinary);
+  }
+
+  @SuppressWarnings("deprecation")
+  public void checkTimeParameters(Connection con) throws Exception {
+    Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+    checkSendTime(
+        ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime())),
+        rs -> assertEquals("18:16:01", rs.getTime(1).toString()),
+        con);
+    checkSendTime(
+        ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime()), utcCal),
+        rs -> assertEquals("18:16:01", rs.getTime(1, utcCal).toString()),
+        con);
+    checkSendTime(
+        ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime() + 123), utcCal),
+        rs ->
+            assertEquals(
+                Time.valueOf("18:16:01").getTime() + 123 - TimeZone.getDefault().getOffset(0),
+                rs.getTime(1).getTime()),
+        con);
+  }
+
+  @Test
+  public void checkNotSupported() throws Exception {
+    checkNotSupported(sharedConn);
+    checkNotSupported(sharedConnBinary);
+  }
+
+  private void checkNotSupported(Connection con) throws SQLException {
+    try (PreparedStatement preparedStatement = con.prepareStatement("SELECT * FROM prepareParam")) {
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> preparedStatement.setRef(1, null),
+          "REF parameter are not supported");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> preparedStatement.setArray(1, null),
+          "Array parameter are not supported");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> preparedStatement.setRowId(1, null),
+          "RowId parameter are not supported");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> preparedStatement.setSQLXML(1, null),
+          "SQLXML parameter are not supported");
+    }
+  }
+
+  private void checkSendBlob(
+      ThrowingConsumer<PreparedStatement, Exception> consumer,
+      ThrowingConsumer<ResultSet, Exception> check,
+      Connection con)
+      throws Exception {
+    checkSend(consumer, check, "prepareParam", con);
+  }
+
+  private void checkSendLong(
+      ThrowingConsumer<PreparedStatement, Exception> consumer,
+      ThrowingConsumer<ResultSet, Exception> check,
+      Connection con)
+      throws Exception {
+    checkSend(consumer, check, "prepareParam2", con);
+  }
+
+  private void checkSendDouble(
+      ThrowingConsumer<PreparedStatement, Exception> consumer,
+      ThrowingConsumer<ResultSet, Exception> check,
+      Connection con)
+      throws Exception {
+    checkSend(consumer, check, "prepareParam3", con);
+  }
+
+  private void checkSendString(
+      ThrowingConsumer<PreparedStatement, Exception> consumer,
+      ThrowingConsumer<ResultSet, Exception> check,
+      Connection con)
+      throws Exception {
+    checkSend(consumer, check, "prepareParam4", con);
+  }
+
+  private void checkSendTimestamp(
+      ThrowingConsumer<PreparedStatement, Exception> consumer,
+      ThrowingConsumer<ResultSet, Exception> check,
+      Connection con)
+      throws Exception {
+    checkSend(consumer, check, "prepareParam5", con);
+  }
+
+  private void checkSendTime(
+      ThrowingConsumer<PreparedStatement, Exception> consumer,
+      ThrowingConsumer<ResultSet, Exception> check,
+      Connection con)
+      throws Exception {
+    checkSend(consumer, check, "prepareParam7", con);
+  }
+
+  private void checkSend(
+      ThrowingConsumer<PreparedStatement, Exception> consumer,
+      ThrowingConsumer<ResultSet, Exception> check,
+      String table,
+      Connection con)
+      throws Exception {
+    Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION");
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO " + table + " VALUES (?)")) {
+      consumer.accept(preparedStatement);
+      preparedStatement.execute();
+    }
+    ResultSet rs = stmt.executeQuery("SELECT * FROM " + table);
+    assertTrue(rs.next());
+    con.rollback();
+    check.accept(rs);
+  }
+
+  @Test
+  public void bigSend() throws SQLException {
+    int maxAllowedPacket = getMaxAllowedPacket();
+    Assumptions.assumeTrue(maxAllowedPacket > 21 * 1024 * 1024);
+    char[] arr = new char[20 * 1024 * 1024];
+    for (int pos = 0; pos < arr.length; pos++) {
+      arr[pos] = (char) ('A' + (pos % 60));
+    }
+    String st = new String(arr);
+    bigSend(sharedConn, st);
+    bigSend(sharedConnBinary, st);
+    try (Connection con = createCon("useEof=false")) {
+      bigSend(con, st);
+    }
+  }
+
+  public void bigSend(Connection con, String st) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE bigTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO bigTest VALUES (?, ?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, st);
+      prep.execute();
+    }
+
+    ResultSet rs = stmt.executeQuery("SELECT t2 from bigTest WHERE t1 = 1");
+    assertTrue(rs.next());
+    assertEquals(st, rs.getString(1));
+    con.commit();
+  }
+
+  @Test
+  public void bigSendError() throws SQLException {
+    int maxAllowedPacket = getMaxAllowedPacket();
+    Assumptions.assumeTrue(maxAllowedPacket < 32 * 1024 * 1024);
+    char[] arr = new char[maxAllowedPacket];
+    for (int pos = 0; pos < arr.length; pos++) {
+      arr[pos] = (char) ('A' + (pos % 60));
+    }
+    boolean expectClosed = maxAllowedPacket >= 16 * 1024 * 1024;
+    String st = new String(arr);
+    try (Connection con = createCon("maxAllowedPacket=" + maxAllowedPacket)) {
+      bigSendError(con, st, expectClosed);
+    }
+    try (Connection con =
+        createCon("useServerPrepStmts=true&maxAllowedPacket=" + maxAllowedPacket)) {
+      bigSendError(con, st, expectClosed);
+    }
+    try (Connection con = createCon("transactionReplay&maxAllowedPacket=" + maxAllowedPacket)) {
+      bigSendError(con, st, expectClosed);
+    }
+  }
+
+  public void bigSendError(Connection con, String st, boolean expectClose) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE bigTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO bigTest VALUES (?, ?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, st);
+      Common.assertThrowsContains(
+          SQLException.class,
+          prep::execute,
+          "Packet too big for current server max_allowed_packet value");
+      assertEquals(expectClose, con.isClosed());
+    }
+    if (!con.isClosed()) con.commit();
+  }
+
+  @Test
+  public void bigSendErrorMax() throws SQLException {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+
+    int maxAllowedPacket = getMaxAllowedPacket();
+    Assumptions.assumeTrue(
+        maxAllowedPacket > 16 * 1024 * 1024 && maxAllowedPacket < 100 * 1024 * 1024);
+    char[] arr = new char[maxAllowedPacket + 100];
+    for (int pos = 0; pos < arr.length; pos++) {
+      arr[pos] = (char) ('A' + (pos % 60));
+    }
+    String st = new String(arr);
+    try (Connection con = createCon("maxAllowedPacket=" + maxAllowedPacket)) {
+      bigSendErrorMax(con, st, true);
+    }
+    try (Connection con =
+        createCon("useServerPrepStmts=true&maxAllowedPacket=" + maxAllowedPacket)) {
+      bigSendErrorMax(con, st, true);
+    }
+    try (Connection con = createCon("transactionReplay&maxAllowedPacket=" + maxAllowedPacket)) {
+      bigSendError(con, st, true);
+    }
+  }
+
+  public void bigSendErrorMax(Connection con, String st, boolean expectClose) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE bigTest");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO bigTest VALUES (?, ?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, st);
+      Common.assertThrowsContains(
+          SQLNonTransientConnectionException.class,
+          prep::execute,
+          "Packet too big for current server max_allowed_packet value");
+      assertEquals(expectClose, con.isClosed());
+    }
+  }
+
+  @FunctionalInterface
+  public interface ThrowingConsumer<T, E extends Exception> {
+    void accept(T t) throws E;
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/PreparedStatementTest.java b/src/test/java/org/mariadb/jdbc/integration/PreparedStatementTest.java
new file mode 100644
index 0000000..038957f
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/PreparedStatementTest.java
@@ -0,0 +1,1278 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigDecimal;
+import java.sql.*;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Random;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.Statement;
+
+public class PreparedStatementTest extends Common {
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS prepare1");
+    stmt.execute("DROP TABLE IF EXISTS prepare2");
+    stmt.execute("DROP TABLE IF EXISTS prepare3");
+    stmt.execute("DROP TABLE IF EXISTS prepare4");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE prepare1 (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("CREATE TABLE prepare2 (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("CREATE TABLE prepare3 (t1 LONGTEXT, t2 LONGTEXT, t3 LONGTEXT, t4 LONGTEXT)");
+    stmt.execute("CREATE TABLE prepare4 (t1 int)");
+    stmt.execute("INSERT INTO prepare4 VALUES (1),(2),(3),(4),(5)");
+    createSequenceTables();
+  }
+
+  @Test
+  public void prep() throws SQLException {
+    try (PreparedStatement stmt = sharedConn.prepareStatement("SELECT ?")) {
+      assertEquals(ResultSet.TYPE_FORWARD_ONLY, stmt.getResultSetType());
+      assertEquals(ResultSet.CONCUR_READ_ONLY, stmt.getResultSetConcurrency());
+      assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+      assertEquals(sharedConn, stmt.getConnection());
+    }
+
+    try (PreparedStatement stmt =
+        sharedConn.prepareStatement(
+            "SELECT ?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
+      assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, stmt.getResultSetType());
+      assertEquals(ResultSet.CONCUR_UPDATABLE, stmt.getResultSetConcurrency());
+      assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+      assertEquals(sharedConn, stmt.getConnection());
+    }
+
+    try (PreparedStatement stmt =
+        sharedConn.prepareStatement(
+            "SELECT ?",
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE,
+            ResultSet.CLOSE_CURSORS_AT_COMMIT)) {
+      assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, stmt.getResultSetType());
+      assertEquals(ResultSet.CONCUR_UPDATABLE, stmt.getResultSetConcurrency());
+      // not supported
+      assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+      assertEquals(sharedConn, stmt.getConnection());
+    }
+  }
+
+  @Test
+  public void execute() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      execute(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      execute(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts&cachePrepStmts=false")) {
+      execute(con);
+    }
+  }
+
+  private void execute(Connection conn) throws SQLException {
+    Statement stmt = conn.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    try (PreparedStatement preparedStatement =
+        conn.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setInt(2, 10);
+
+      assertFalse(preparedStatement.execute());
+
+      ParameterMetaData paramMeta = preparedStatement.getParameterMetaData();
+      paramMeta.getParameterTypeName(1);
+      paramMeta = preparedStatement.getParameterMetaData();
+      paramMeta.getParameterTypeName(1);
+
+      // verification
+      ResultSet rs = stmt.executeQuery("SELECT * FROM prepare1");
+      assertTrue(rs.next());
+      assertEquals(5, rs.getInt(1));
+      assertEquals(10, rs.getInt(2));
+      assertFalse(rs.next());
+
+      // prepare is already done. must only execute.
+      preparedStatement.setInt(1, 7);
+      preparedStatement.setInt(2, 12);
+      assertFalse(preparedStatement.execute());
+
+      rs = stmt.executeQuery("SELECT * FROM prepare1 WHERE t1 > 5");
+      assertTrue(rs.next());
+      assertEquals(7, rs.getInt(1));
+      assertEquals(12, rs.getInt(2));
+      assertFalse(rs.next());
+    }
+
+    try (PreparedStatement preparedStatement =
+        conn.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      preparedStatement.setInt(1, 4);
+      assertTrue(preparedStatement.execute());
+      ResultSet rs = preparedStatement.getResultSet();
+      assertTrue(rs.next());
+      assertEquals(5, rs.getInt(1));
+      assertEquals(10, rs.getInt(2));
+      assertTrue(rs.next());
+      assertEquals(7, rs.getInt(1));
+      assertEquals(12, rs.getInt(2));
+      assertFalse(rs.next());
+
+      preparedStatement.setMaxRows(1);
+      preparedStatement.setInt(1, 4);
+      assertTrue(preparedStatement.execute());
+      rs = preparedStatement.getResultSet();
+      assertTrue(rs.next());
+      assertEquals(5, rs.getInt(1));
+      assertEquals(10, rs.getInt(2));
+      if (isMariaDBServer()) {
+        // setMaxRows() has no effect for mysql, since not supporting SET STATEMENT SQL_SELECT_LIMIT
+        assertFalse(rs.next());
+      }
+    }
+
+    // prepare not cached (length > 8K)
+    StringBuilder sql = new StringBuilder("INSERT INTO prepare1(t1, t2) VALUES (?,?) /*");
+    for (int i = 0; i < 900; i++) {
+      sql.append("1234567890");
+    }
+    sql.append("*/");
+    stmt.execute("TRUNCATE prepare1");
+    try (PreparedStatement preparedStatement = conn.prepareStatement(sql.toString())) {
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setInt(2, 10);
+      assertFalse(preparedStatement.execute());
+
+      ParameterMetaData paramMeta = preparedStatement.getParameterMetaData();
+      paramMeta.getParameterTypeName(1);
+      paramMeta = preparedStatement.getParameterMetaData();
+      paramMeta.getParameterTypeName(1);
+
+      // verification
+      ResultSet rs = stmt.executeQuery("SELECT * FROM prepare1");
+      assertTrue(rs.next());
+      assertEquals(5, rs.getInt(1));
+      assertEquals(10, rs.getInt(2));
+      assertFalse(rs.next());
+
+      // prepare is already done. must only execute.
+      preparedStatement.setInt(1, 7);
+      preparedStatement.setInt(2, 12);
+      assertFalse(preparedStatement.execute());
+
+      rs = stmt.executeQuery("SELECT * FROM prepare1 WHERE t1 > 5");
+      assertTrue(rs.next());
+      assertEquals(7, rs.getInt(1));
+      assertEquals(12, rs.getInt(2));
+      assertFalse(rs.next());
+    }
+  }
+
+  @Test
+  public void executeWithoutAllParameters() throws SQLException {
+    executeWithoutAllParameters(sharedConn);
+    executeWithoutAllParameters(sharedConnBinary);
+  }
+
+  public void executeWithoutAllParameters(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+      preparedStatement.setInt(2, 10);
+      Common.assertThrowsContains(
+          SQLException.class,
+          preparedStatement::executeUpdate,
+          "Parameter at position 1 is not " + "set");
+
+      preparedStatement.setNull(1, Types.VARBINARY);
+      preparedStatement.executeUpdate();
+      ResultSet rs = stmt.executeQuery("SELECT * FROM prepare1");
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt(1));
+      assertEquals(10, rs.getInt(2));
+      assertFalse(rs.next());
+    }
+  }
+
+  @Test
+  public void executeUpdate() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setInt(2, 10);
+      assertEquals(1, preparedStatement.executeUpdate());
+
+      // verification that query without resultset return an empty resultset
+      preparedStatement.clearParameters();
+      Common.assertThrowsContains(
+          SQLException.class,
+          preparedStatement::executeQuery,
+          "Parameter at position 1 is not set");
+      preparedStatement.setInt(2, 11);
+      preparedStatement.setInt(1, 6);
+      ResultSet rs0 = preparedStatement.executeQuery();
+      assertFalse(rs0.next());
+
+      // verification
+      ResultSet rs = stmt.executeQuery("SELECT * FROM prepare1");
+      assertTrue(rs.next());
+      assertEquals(5, rs.getInt(1));
+      assertEquals(10, rs.getInt(2));
+      assertTrue(rs.next());
+      assertEquals(6, rs.getInt(1));
+      assertEquals(11, rs.getInt(2));
+      assertFalse(rs.next());
+    }
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement("SELECT * FROM prepare1")) {
+      Common.assertThrowsContains(
+          SQLException.class,
+          preparedStatement::executeUpdate,
+          "the given SQL statement produces an unexpected ResultSet object");
+    }
+  }
+
+  @Test
+  public void executeQuery() throws SQLException {
+    executeQuery(sharedConn);
+    executeQuery(sharedConnBinary);
+    try (Connection con = createCon("useServerPrepStmts=true&enableSkipMeta=false")) {
+      executeQuery(con);
+    }
+    try (Connection con = createCon("useServerPrepStmts=true&enableSkipMeta=true")) {
+      executeQuery(con);
+    }
+  }
+
+  @Test
+  public void tryMaybeNotPreparable() throws SQLException {
+    try (Connection con = createCon("useServerPrepStmts")) {
+      try (PreparedStatement prep = con.prepareStatement("CREATE TABLE maybeCreate(id int)")) {
+        prep.execute();
+      }
+    } finally {
+      sharedConn.createStatement().execute("DROP TABLE IF EXISTS maybeCreate");
+    }
+    try (Connection con = createCon("useServerPrepStmts")) {
+      try (PreparedStatement prep =
+          con.prepareStatement("CREATE PROCEDURE maybeProc(IN  I date) BEGIN SELECT I; END")) {
+        prep.execute();
+      }
+    } finally {
+      sharedConn.createStatement().execute("DROP PROCEDURE IF EXISTS maybeProc");
+    }
+  }
+
+  private void executeQuery(Connection con) throws SQLException {
+    // https://jira.mariadb.org/browse/XPT-282
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS prepare10");
+    stmt.execute("CREATE TABLE prepare10 (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("INSERT INTO prepare10(t1, t2) VALUES (5,10), (40,20), (127,45)");
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("SELECT * FROM prepare10 WHERE t1 > ?")) {
+      preparedStatement.setInt(1, 20);
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      assertEquals(40, rs.getInt(1));
+      assertEquals(20, rs.getInt(2));
+      assertTrue(rs.next());
+      assertEquals(127, rs.getInt(1));
+      assertEquals(45, rs.getInt(2));
+      assertFalse(rs.next());
+      Common.assertThrowsContains(
+          SQLException.class, () -> preparedStatement.setInt(-20, 2), "wrong parameter index -20");
+
+      preparedStatement.setInt(1, 50);
+      rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      assertEquals(127, rs.getInt(1));
+      assertEquals(45, rs.getInt(2));
+      assertFalse(rs.next());
+      Common.assertThrowsContains(
+          SQLException.class, () -> preparedStatement.setInt(-20, 2), "wrong parameter index -20");
+      stmt.execute("ALTER TABLE prepare10 ADD COLUMN t3 varchar(20) default 'tt'");
+      preparedStatement.setInt(1, 20);
+      rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      assertEquals(40, rs.getInt(1));
+      assertEquals(20, rs.getInt(2));
+      assertEquals("tt", rs.getString(3));
+    }
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("SELECT * FROM prepare10 WHERE t1 > ?")) {
+      preparedStatement.setInt(1, 20);
+      preparedStatement.executeQuery();
+    }
+  }
+
+  @Test
+  public void clearParameters() throws Exception {
+    // error crashing maxscale 6.1.x
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.1.")
+            && !"skysql-ha".equals(System.getenv("srv")));
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts=false")) {
+      clearParameters(con);
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts")) {
+      clearParameters(con);
+    }
+  }
+
+  public void clearParameters(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setInt(2, 10);
+      preparedStatement.clearParameters();
+      assertThrows(SQLException.class, preparedStatement::execute);
+    }
+  }
+
+  @Test
+  public void closeOnCompletion() throws SQLException {
+    PreparedStatement preparedStatement =
+        sharedConn.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?");
+    Assertions.assertFalse(preparedStatement.isCloseOnCompletion());
+    preparedStatement.closeOnCompletion();
+    Assertions.assertTrue(preparedStatement.isCloseOnCompletion());
+    Assertions.assertFalse(preparedStatement.isClosed());
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    Assertions.assertFalse(rs.isClosed());
+    Assertions.assertFalse(preparedStatement.isClosed());
+    rs.close();
+    Assertions.assertTrue(rs.isClosed());
+    Assertions.assertTrue(preparedStatement.isClosed());
+  }
+
+  @Test
+  public void executeBatch() throws SQLException {
+    executeBatch(sharedConn);
+    executeBatch(sharedConnBinary);
+    try (Connection con = createCon("allowLocalInfile=true")) {
+      executeBatch(con);
+    }
+    try (Connection con = createCon("allowLocalInfile=true&useServerPrepStmts=true")) {
+      executeBatch(con);
+    }
+  }
+
+  private void executeBatch(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    stmt.execute("START TRANSACTION");
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+
+      try (PreparedStatement preparedStatement2 =
+          con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+        preparedStatement2.setInt(1, 15);
+        preparedStatement2.setInt(2, 110);
+        preparedStatement2.addBatch();
+        preparedStatement2.executeBatch();
+      }
+
+      int[] res = preparedStatement.executeBatch();
+      assertEquals(0, res.length);
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setInt(2, 10);
+      preparedStatement.addBatch();
+      res = preparedStatement.executeBatch();
+      assertEquals(1, res.length);
+      res = preparedStatement.executeBatch();
+      assertEquals(0, res.length);
+    }
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+      preparedStatement.setInt(1, 40);
+      preparedStatement.setInt(2, 20);
+      preparedStatement.addBatch();
+      preparedStatement.setInt(1, 127);
+      preparedStatement.setInt(2, 45);
+      preparedStatement.addBatch();
+      int[] res = preparedStatement.executeBatch();
+      assertEquals(2, res.length);
+    }
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      preparedStatement.setInt(1, 20);
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      assertEquals(40, rs.getInt(1));
+      assertEquals(20, rs.getInt(2));
+      assertTrue(rs.next());
+      assertEquals(127, rs.getInt(1));
+      assertEquals(45, rs.getInt(2));
+      assertFalse(rs.next());
+    }
+    con.commit();
+  }
+
+  @Test
+  public void executeWrongBatch() throws SQLException {
+    executeWrongBatch(sharedConn);
+    executeWrongBatch(sharedConnBinary);
+    try (Connection con = createCon("useBulkStmts=false&useServerPrepStmts=true")) {
+      executeWrongBatch(con);
+    }
+  }
+
+  private void executeWrongBatch(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    stmt.execute("SET sql_mode = concat(@@sql_mode,',ERROR_FOR_DIVISION_BY_ZERO')");
+    try (PreparedStatement preparedStatement = con.prepareStatement("SELECT 5/?")) {
+      preparedStatement.setInt(1, 5);
+      preparedStatement.addBatch();
+      preparedStatement.executeBatch();
+
+      preparedStatement.setInt(1, 5);
+      preparedStatement.addBatch();
+      preparedStatement.setInt(1, 0);
+      preparedStatement.addBatch();
+      try {
+        preparedStatement.executeBatch();
+      } catch (BatchUpdateException e) {
+        // eat
+      }
+    }
+  }
+
+  @Test
+  public void executeBatchMultiple() throws SQLException {
+    // xpand don't support DO command
+    Assumptions.assumeFalse(isXpand());
+    try (Connection con = createCon("allowMultiQueries&useBulkStmts=false")) {
+      executeBatchMultiple(con);
+    }
+  }
+
+  private void executeBatchMultiple(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?);DO 1")) {
+      int[] res = preparedStatement.executeBatch();
+      assertEquals(0, res.length);
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setInt(2, 10);
+      preparedStatement.addBatch();
+      res = preparedStatement.executeBatch();
+      assertEquals(1, res.length);
+      res = preparedStatement.executeBatch();
+      assertEquals(0, res.length);
+    }
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?);DO 1")) {
+      preparedStatement.setInt(1, 40);
+      preparedStatement.setInt(2, 20);
+      preparedStatement.addBatch();
+      preparedStatement.setInt(1, 127);
+      preparedStatement.setInt(2, 45);
+      preparedStatement.addBatch();
+      int[] res = preparedStatement.executeBatch();
+      assertEquals(2, res.length);
+    }
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      preparedStatement.setInt(1, 20);
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      assertEquals(40, rs.getInt(1));
+      assertEquals(20, rs.getInt(2));
+      assertTrue(rs.next());
+      assertEquals(127, rs.getInt(1));
+      assertEquals(45, rs.getInt(2));
+      assertFalse(rs.next());
+    }
+  }
+
+  @Test
+  public void executeLargeBatch() throws SQLException {
+    executeLargeBatch(sharedConn);
+    executeLargeBatch(sharedConnBinary);
+    try (Connection con = createCon("allowLocalInfile=true")) {
+      executeLargeBatch(con);
+    }
+    try (Connection con = createCon("allowLocalInfile=true&useServerPrepStmts=true")) {
+      executeLargeBatch(con);
+    }
+  }
+
+  private void executeLargeBatch(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+      preparedStatement.executeLargeBatch();
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setInt(2, 10);
+      preparedStatement.addBatch();
+      preparedStatement.executeLargeBatch();
+      preparedStatement.executeLargeBatch();
+    }
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+      preparedStatement.setInt(1, 40);
+      preparedStatement.setInt(2, 20);
+      preparedStatement.addBatch();
+      preparedStatement.setInt(1, 127);
+      preparedStatement.setInt(2, 45);
+      preparedStatement.addBatch();
+      preparedStatement.executeLargeBatch();
+    }
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      preparedStatement.setInt(1, 20);
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      assertEquals(40, rs.getInt(1));
+      assertEquals(20, rs.getInt(2));
+      assertTrue(rs.next());
+      assertEquals(127, rs.getInt(1));
+      assertEquals(45, rs.getInt(2));
+      assertFalse(rs.next());
+    }
+  }
+
+  @Test
+  public void executeBatchGenerated() throws SQLException {
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "INSERT INTO prepare2(t2) VALUES (?)", java.sql.Statement.RETURN_GENERATED_KEYS)) {
+      preparedStatement.setInt(1, 10);
+      preparedStatement.addBatch();
+      preparedStatement.setInt(1, 20);
+      preparedStatement.addBatch();
+      preparedStatement.executeBatch();
+      ResultSet rs = preparedStatement.getGeneratedKeys();
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt(1));
+      assertTrue(rs.next());
+      assertEquals(2, rs.getInt(1));
+      assertFalse(rs.next());
+    }
+
+    try (PreparedStatement preparedStatement =
+        sharedConnBinary.prepareStatement(
+            "INSERT INTO prepare2(t2) VALUES (?)", java.sql.Statement.RETURN_GENERATED_KEYS)) {
+      preparedStatement.setInt(1, 10);
+      preparedStatement.addBatch();
+      preparedStatement.setInt(1, 20);
+      preparedStatement.addBatch();
+      preparedStatement.executeBatch();
+      ResultSet rs = preparedStatement.getGeneratedKeys();
+      assertTrue(rs.next());
+      assertEquals(3, rs.getInt(1));
+      assertTrue(rs.next());
+      assertEquals(4, rs.getInt(1));
+      assertFalse(rs.next());
+    }
+
+    try (Connection con = createCon("allowMultiQueries")) {
+      try (PreparedStatement preparedStatement =
+          con.prepareStatement(
+              "INSERT INTO prepare2(t2) VALUES (?);INSERT INTO prepare2(t2) VALUES (?)",
+              java.sql.Statement.RETURN_GENERATED_KEYS)) {
+        preparedStatement.setInt(1, 30);
+        preparedStatement.setInt(2, 50);
+        preparedStatement.execute();
+        ResultSet rs = preparedStatement.getGeneratedKeys();
+        assertTrue(rs.next());
+        assertEquals(5, rs.getInt(1));
+        assertTrue(rs.next());
+        assertEquals(6, rs.getInt(1));
+        assertFalse(rs.next());
+
+        preparedStatement.setInt(1, 210);
+        preparedStatement.setInt(2, 110);
+        preparedStatement.addBatch();
+        preparedStatement.setInt(1, 220);
+        preparedStatement.setInt(2, 220);
+        preparedStatement.addBatch();
+        preparedStatement.executeBatch();
+
+        rs = preparedStatement.getGeneratedKeys();
+        assertTrue(rs.next());
+        assertEquals(7, rs.getInt(1));
+        assertTrue(rs.next());
+        assertEquals(8, rs.getInt(1));
+        assertTrue(rs.next());
+        assertEquals(9, rs.getInt(1));
+        assertTrue(rs.next());
+        assertEquals(10, rs.getInt(1));
+        assertFalse(rs.next());
+      }
+    }
+  }
+
+  @Test
+  public void emptyExecuteBatch() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE prepare1");
+    stmt.execute("INSERT INTO prepare1(t1, t2) VALUES (5,10), (40,20), (127,45)");
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      assertEquals(0, preparedStatement.executeBatch().length);
+    }
+    try (PreparedStatement preparedStatement =
+        sharedConnBinary.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      assertEquals(0, preparedStatement.executeBatch().length);
+    }
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      assertEquals(0, preparedStatement.executeLargeBatch().length);
+    }
+    try (PreparedStatement preparedStatement =
+        sharedConnBinary.prepareStatement("SELECT * FROM prepare1 WHERE t1 > ?")) {
+      assertEquals(0, preparedStatement.executeLargeBatch().length);
+    }
+  }
+
+  @Test
+  public void moreResults() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      moreResults(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      moreResults(con);
+    }
+  }
+
+  private void moreResults(Connection con) throws SQLException {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS multi");
+    stmt.setFetchSize(3);
+    stmt.execute(
+        "CREATE PROCEDURE multi() BEGIN SELECT * from sequence_1_to_10; SELECT * FROM"
+            + " sequence_1_to_10;SELECT 2; END");
+    stmt.execute("CALL multi()");
+    Assertions.assertTrue(stmt.getMoreResults());
+    ResultSet rs = stmt.getResultSet();
+    int i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+    Assertions.assertEquals(11, i);
+    stmt.setFetchSize(3);
+    PreparedStatement prep = con.prepareStatement("CALL multi()");
+    rs = prep.executeQuery();
+    Assertions.assertFalse(rs.isClosed());
+    prep.setFetchSize(0); // force more result to load all remaining result-set
+    Assertions.assertTrue(prep.getMoreResults());
+    Assertions.assertTrue(rs.isClosed());
+    rs = prep.getResultSet();
+    i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+
+    prep.setFetchSize(3);
+    rs = prep.executeQuery();
+    Assertions.assertFalse(rs.isClosed());
+    prep.setFetchSize(0); // force more result to load all remaining result-set
+    Assertions.assertTrue(prep.getMoreResults(java.sql.Statement.KEEP_CURRENT_RESULT));
+    Assertions.assertFalse(rs.isClosed());
+    i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+    Assertions.assertEquals(11, i);
+    rs = prep.getResultSet();
+    i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+    Assertions.assertEquals(11, i);
+
+    rs = prep.executeQuery();
+    prep.close();
+    assertTrue(rs.isClosed());
+  }
+
+  @Test
+  public void moreRowLimitedResults() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      moreRowLimitedResults(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      moreRowLimitedResults(con);
+    }
+  }
+
+  private void moreRowLimitedResults(Connection con) throws SQLException {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS multi");
+    stmt.setFetchSize(3);
+    stmt.setMaxRows(5);
+    stmt.execute(
+        "CREATE PROCEDURE multi() BEGIN SELECT * from prepare4; SELECT * FROM prepare4;SELECT 2;"
+            + " END");
+    stmt.execute("CALL multi()");
+    Assertions.assertTrue(stmt.getMoreResults());
+    ResultSet rs = stmt.getResultSet();
+    int i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+    Assertions.assertEquals(6, i);
+    stmt.setFetchSize(3);
+    PreparedStatement prep = con.prepareStatement("CALL multi()");
+    prep.setMaxRows(20);
+    rs = prep.executeQuery();
+    Assertions.assertFalse(rs.isClosed());
+    prep.setFetchSize(0); // force more result to load all remaining result-set
+    Assertions.assertTrue(prep.getMoreResults());
+    Assertions.assertTrue(rs.isClosed());
+    rs = prep.getResultSet();
+    i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+
+    prep.setFetchSize(3);
+    prep.setMaxRows(5);
+    rs = prep.executeQuery();
+    Assertions.assertFalse(rs.isClosed());
+    prep.setFetchSize(0); // force more result to load all remaining result-set
+    Assertions.assertTrue(prep.getMoreResults(java.sql.Statement.KEEP_CURRENT_RESULT));
+    Assertions.assertFalse(rs.isClosed());
+    i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+    Assertions.assertEquals(6, i);
+    rs = prep.getResultSet();
+    i = 1;
+    while (rs.next()) {
+      Assertions.assertEquals(i++, rs.getInt(1));
+    }
+    Assertions.assertEquals(6, i);
+
+    rs = prep.executeQuery();
+    prep.close();
+    assertTrue(rs.isClosed());
+  }
+
+  @Test
+  public void prepareWithError() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      prepareWithError(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      prepareWithError(con);
+    }
+  }
+
+  private void prepareWithError(Connection con) throws SQLException {
+    Assumptions.assumeTrue(isMariaDBServer());
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS prepareError");
+    stmt.setFetchSize(3);
+    stmt.execute("CREATE TABLE prepareError(id int primary key, val varchar(10))");
+    stmt.execute("INSERT INTO prepareError(id, val) values (1, 'val1')");
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO prepareError(id, val) VALUES (?,?)")) {
+      prep.setInt(1, 1);
+      prep.setString(2, "val2");
+      try {
+        prep.execute();
+        fail();
+      } catch (SQLException e) {
+        assertTrue(
+            e.getMessage()
+                    .contains("Duplicate key in container: `testj`.`prepareError` Primary key:")
+                || e.getMessage().contains("Duplicate entry '1' for key 'PRIMARY'"));
+      }
+    }
+    try (PreparedStatement prep = con.prepareStatement("Wrong command")) {
+      try {
+        prep.execute();
+        fail();
+      } catch (SQLException e) {
+        assertTrue(
+            e.getMessage().contains("syntax error: syntax error near")
+                || e.getMessage().contains("You have an error in your SQL syntax"));
+      }
+    }
+  }
+
+  @Test
+  public void streamNotFinished() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(2);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10");
+
+    Statement stmt2 = sharedConn.createStatement();
+    ResultSet rs2 = stmt2.executeQuery("SELECT 1");
+    rs2.next();
+    assertEquals(1, rs2.getInt(1));
+    for (int i = 1; i <= 10; i++) {
+      rs.next();
+      assertEquals(i, rs.getInt(1));
+    }
+  }
+
+  @Test
+  public void expectedError() throws SQLException {
+    try (PreparedStatement prep = sharedConn.prepareStatement("SELECT ?")) {
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.addBatch("SELECT 1"),
+          "addBatch(String sql) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.execute("SELECT 1"),
+          "execute(String sql) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.execute("SELECT 1", Statement.NO_GENERATED_KEYS),
+          "execute(String sql, int autoGeneratedKeys) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.execute("SELECT 1", new int[] {}),
+          "execute(String sql, int[] columnIndexes) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.execute("SELECT 1", new String[] {}),
+          "execute(String sql, String[] columnNames) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeQuery("SELECT 1"),
+          "executeQuery(String sql) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeUpdate("SELECT 1"),
+          "executeUpdate(String sql) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeUpdate("SELECT 1", Statement.NO_GENERATED_KEYS),
+          "executeUpdate(String sql, int autoGeneratedKeys) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeUpdate("SELECT 1", new int[] {}),
+          "executeUpdate(String sql, int[] columnIndexes) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeUpdate("SELECT 1", new String[] {}),
+          "executeUpdate(String sql, String[] columnNames) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeLargeUpdate("SELECT 1"),
+          "executeLargeUpdate(String sql) cannot be called on preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeLargeUpdate("SELECT 1", Statement.NO_GENERATED_KEYS),
+          "executeLargeUpdate(String sql, int autoGeneratedKeys) cannot be called on"
+              + " preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeLargeUpdate("SELECT 1", new int[] {}),
+          "executeLargeUpdate(String sql, int[] columnIndexes) cannot be called on"
+              + " preparedStatement");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.executeLargeUpdate("SELECT 1", new String[] {}),
+          "executeLargeUpdate(String sql, String[] columnNames) cannot be called on"
+              + " preparedStatement");
+    }
+  }
+
+  @Test
+  public void largeMaxRows() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      largeMaxRows(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      largeMaxRows(con);
+    }
+  }
+
+  private void largeMaxRows(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS largeMaxRows");
+    stmt.setFetchSize(3);
+    stmt.execute("CREATE TABLE largeMaxRows(id int)");
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO largeMaxRows(id) VALUE (?)")) {
+      for (int i = 1; i < 51; i++) {
+        prep.setInt(1, i);
+        prep.execute();
+      }
+    }
+
+    try (PreparedStatement prep = con.prepareStatement("SELECT * FROM largeMaxRows")) {
+      assertEquals(0L, prep.getLargeMaxRows());
+      ResultSet rs = prep.executeQuery();
+      int i = 0;
+      while (rs.next()) {
+        i++;
+        assertEquals(i, rs.getInt(1));
+      }
+      assertEquals(50, i);
+
+      try {
+        prep.setLargeMaxRows(-1);
+        Assertions.fail();
+      } catch (SQLException e) {
+        assertTrue(e.getMessage().contains("max rows cannot be negative"));
+      }
+      prep.setLargeMaxRows(10);
+      assertEquals(10L, prep.getLargeMaxRows());
+
+      rs = prep.executeQuery();
+      i = 0;
+      while (rs.next()) {
+        i++;
+        assertEquals(i, rs.getInt(1));
+      }
+      assertEquals(10, i);
+
+      prep.setQueryTimeout(2);
+      rs = prep.executeQuery();
+      i = 0;
+      while (rs.next()) {
+        i++;
+        assertEquals(i, rs.getInt(1));
+      }
+      assertEquals(10, i);
+
+      prep.setQueryTimeout(20);
+      prep.setLargeMaxRows(0);
+      rs = prep.executeQuery();
+      i = 0;
+      while (rs.next()) {
+        i++;
+        assertEquals(i, rs.getInt(1));
+      }
+      assertEquals(50, i);
+      prep.setQueryTimeout(0);
+      prep.setQueryTimeout(0);
+    }
+  }
+
+  @Test
+  public void largeMaxRowsBatch() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      largeMaxRowsBatch(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      largeMaxRowsBatch(con);
+    }
+  }
+
+  private void prepareInsert(PreparedStatement prep) throws SQLException {
+    prep.setInt(1, 0);
+    prep.addBatch();
+    prep.setInt(1, 1);
+    prep.addBatch();
+    prep.executeBatch();
+  }
+
+  private void largeMaxRowsBatch(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS large_max_rows_batch");
+    stmt.setFetchSize(3);
+    stmt.execute("CREATE TABLE large_max_rows_batch(id int)");
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO large_max_rows_batch(id) VALUE (?)")) {
+      prepareInsert(prep);
+
+      prep.setMaxRows(1);
+      prepareInsert(prep);
+
+      prep.setQueryTimeout(1);
+      prepareInsert(prep);
+
+      prep.setMaxRows(0);
+      prepareInsert(prep);
+
+      prep.setLargeMaxRows(2);
+      prepareInsert(prep);
+
+      prep.setQueryTimeout(0);
+      prepareInsert(prep);
+    }
+    ResultSet rs = stmt.executeQuery("SELECT count(*) FROM large_max_rows_batch");
+    rs.next();
+    assertEquals(12, rs.getInt(1));
+  }
+
+  @Test
+  public void decrementCache() throws SQLException {
+    decrementCache("&useServerPrepStmts=true&prepStmtCacheSize=5");
+    decrementCache("&useServerPrepStmts=true&useServerPrepStmts=false");
+  }
+
+  public void decrementCache(String connString) throws SQLException {
+    try (Connection con = createCon(connString)) {
+      PreparedStatement prep = con.prepareStatement("SELECT 1");
+      prep.execute();
+      PreparedStatement prep2 = con.prepareStatement("SELECT 1");
+      prep2.execute();
+
+      for (int i = 1; i < 10; i++) {
+        try (PreparedStatement prep1 = con.prepareStatement("SELECT " + i)) {
+          prep1.execute();
+          prep1.setQueryTimeout(1);
+        }
+      }
+
+      prep.setQueryTimeout(1); // will close prepare
+      prep.setQueryTimeout(2); // will close prepare
+      prep.execute();
+      prep.close();
+      prep2.close();
+    }
+  }
+
+  @Test
+  public void prepareStatementConcur() throws SQLException {
+    try (Connection con = createCon("&useServerPrepStmts=false")) {
+      prepareStatementConcur(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts")) {
+      prepareStatementConcur(con);
+    }
+    try (Connection con = createCon("&useServerPrepStmts=false&disablePipeline")) {
+      prepareStatementConcur(con);
+    }
+  }
+
+  private void prepareStatementConcur(Connection con) throws SQLException {
+    try (PreparedStatement prep = con.prepareStatement("SELECT 1", new int[] {})) {
+      prep.execute();
+    }
+
+    try (PreparedStatement prep = con.prepareStatement("SELECT 1", new String[] {})) {
+      prep.execute();
+    }
+
+    try (PreparedStatement prep =
+        con.prepareStatement("SELECT 1", Statement.RETURN_GENERATED_KEYS)) {
+      assertEquals(ResultSet.CONCUR_READ_ONLY, prep.getResultSetConcurrency());
+      assertEquals(ResultSet.TYPE_FORWARD_ONLY, prep.getResultSetType());
+      prep.execute();
+    }
+    try (PreparedStatement prep =
+        con.prepareStatement(
+            "SELECT 1", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
+      assertEquals(ResultSet.CONCUR_UPDATABLE, prep.getResultSetConcurrency());
+      assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, prep.getResultSetType());
+
+      prep.execute();
+    }
+  }
+
+  @Test
+  public void more2BytesParameters() throws Throwable {
+    int[] rnds = new int[100000];
+    StringBuilder sb = new StringBuilder("select ?");
+    for (int i = 0; i < 100000; i++) {
+      rnds[i] = (int) (Math.random() * 1000);
+    }
+    for (int i = 1; i < 100000; i++) {
+      sb.append(",?");
+    }
+    String sql = sb.toString();
+
+    try (PreparedStatement st = sharedConnBinary.prepareStatement(sql)) {
+      for (int i = 1; i <= 100000; i++) {
+        st.setInt(i, rnds[i - 1]);
+      }
+      try {
+        st.executeQuery();
+        fail();
+      } catch (SQLException e) {
+        assertTrue(
+            e.getMessage().contains("memory exhausted near \",\"")
+                || e.getMessage().contains("Prepared statement contains too many placeholders"));
+      }
+    }
+    assertTrue(sharedConnBinary.isValid(1));
+  }
+
+  private String generateLongText(int len) {
+    int leftLimit = 97; // letter 'a'
+    int rightLimit = 122; // letter 'z'
+    Random random = new Random();
+    return random
+        .ints(leftLimit, rightLimit)
+        .limit(len)
+        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
+        .toString();
+  }
+
+  @Test
+  public void skippingRes() throws SQLException {
+    int maxAllowedPacket = getMaxAllowedPacket();
+    Assumptions.assumeTrue(maxAllowedPacket > 35_000_000);
+    skippingRes(sharedConn);
+    skippingRes(sharedConnBinary);
+    try (Connection compressText =
+        createCon("useCompression&maxAllowedPacket=" + maxAllowedPacket)) {
+      skippingRes(compressText);
+    }
+    try (Connection compressBinary =
+        createCon("useCompression&useServerPrepStmts&maxAllowedPacket=" + maxAllowedPacket)) {
+      skippingRes(compressBinary);
+    }
+  }
+
+  private void skippingRes(java.sql.Connection con) throws SQLException {
+    con.createStatement().execute("TRUNCATE prepare3");
+    String longText = generateLongText(20_000_000);
+    String mediumText = generateLongText(10_000_000);
+    String smallIntText = generateLongText(60_000);
+
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO prepare3 values (?,?,?,?)")) {
+      prep.setString(1, longText);
+      prep.setString(2, mediumText);
+      prep.setString(3, smallIntText);
+      prep.setString(4, "expected");
+      prep.execute();
+    }
+
+    try (PreparedStatement prep = con.prepareStatement("SELECT * FROM prepare3")) {
+      ResultSet rs = prep.executeQuery();
+      rs.next();
+      assertEquals("expected", rs.getString(4));
+      assertEquals(smallIntText, rs.getString(3));
+      assertEquals(mediumText, rs.getString(2));
+      assertEquals(longText, rs.getString(1));
+    }
+  }
+
+  @Test
+  public void wrongPosition() throws SQLException {
+    try (PreparedStatement prep = sharedConn.prepareStatement("SELECT 1 FROM DUAL WHERE 0=1")) {
+      ResultSet rs = prep.executeQuery();
+      Common.assertThrowsContains(SQLException.class, () -> rs.getString(1), "wrong row position");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.getString("1"), "wrong row position");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.getObject(1, String.class), "wrong row position");
+    }
+    try (PreparedStatement prep = sharedConn.prepareStatement("SELECT 1 FROM DUAL")) {
+      ResultSet rs = prep.executeQuery();
+      rs.next();
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.getString(-1),
+          "Wrong index position. Is -1 but must be in 1-1 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.getString(10),
+          "Wrong index position. Is 10 but must be in 1-1 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.getObject(-1, String.class),
+          "Wrong index position. Is -1 but must be in 1-1 range");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.getObject(10, String.class),
+          "Wrong index position. Is 10 but must be in 1-1 range");
+    }
+  }
+
+  @Test
+  public void prepareStmtToString() throws SQLException {
+    prepareStmtToString(sharedConn, "ClientPreparedStatement");
+    prepareStmtToString(sharedConnBinary, "ServerPreparedStatement");
+  }
+
+  public void prepareStmtToString(java.sql.Connection conn, String prefix) throws SQLException {
+    try (PreparedStatement preparedStatement =
+        conn.prepareStatement("INSERT INTO prepare1(t1, t2) VALUES (?,?)")) {
+
+      assertEquals(
+          prefix + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)', parameters:[]}",
+          preparedStatement.toString());
+
+      preparedStatement.setInt(1, 5);
+      preparedStatement.setLong(2, 10L);
+      assertEquals(
+          prefix + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)', parameters:[5,10]}",
+          preparedStatement.toString());
+
+      preparedStatement.setNull(2, Types.VARBINARY);
+      assertEquals(
+          prefix + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)', parameters:[5,null]}",
+          preparedStatement.toString());
+      preparedStatement.setNull(1, Types.VARBINARY);
+      preparedStatement.setBytes(2, new byte[] {(byte) 'a', (byte) 'b'});
+      assertEquals(
+          prefix
+              + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)', parameters:[null,_binary 'ab']}",
+          preparedStatement.toString());
+
+      preparedStatement.setBlob(1, new MariaDbBlob(new byte[] {0, 1, 2, 3, 4, 5}));
+      preparedStatement.setAsciiStream(2, new ByteArrayInputStream("test3".getBytes()));
+      assertEquals(
+          prefix
+              + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)', parameters:[<interface"
+              + " java.sql.Blob>,<class java.io.InputStream>]}",
+          preparedStatement.toString());
+
+      preparedStatement.setObject(1, LocalDateTime.parse("2010-01-12T01:55:12"));
+      preparedStatement.setObject(2, LocalDate.parse("2011-01-01"));
+      assertEquals(
+          prefix
+              + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)', parameters:['2010-01-12"
+              + " 01:55:12','2011-01-01']}",
+          preparedStatement.toString());
+
+      preparedStatement.setBigDecimal(1, new BigDecimal("158.9876543210"));
+      preparedStatement.setString(2, "test");
+      assertEquals(
+          prefix
+              + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)',"
+              + " parameters:[158.9876543210,'test']}",
+          preparedStatement.toString());
+
+      preparedStatement.setString(3, "unusedParam");
+      assertEquals(
+          prefix
+              + "{sql:'INSERT INTO prepare1(t1, t2) VALUES (?,?)',"
+              + " parameters:[158.9876543210,'test','unusedParam']}",
+          preparedStatement.toString());
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ProcedureParameterTest.java b/src/test/java/org/mariadb/jdbc/integration/ProcedureParameterTest.java
new file mode 100644
index 0000000..7382bfb
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ProcedureParameterTest.java
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.math.BigDecimal;
+import java.sql.*;
+import java.util.BitSet;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+
+public class ProcedureParameterTest extends Common {
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE PROCEDURE useParameterName(a int) begin select a; end");
+    stmt.execute(
+        "CREATE PROCEDURE withStrangeParameter(IN a DECIMAL(10,2)) begin select a as b; end");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS useParameterName");
+    stmt.execute("DROP PROCEDURE IF EXISTS withStrangeParameter");
+  }
+
+  @Test
+  public void callUseParameterName() throws Exception {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+    // https://jira.mariadb.org/browse/XPT-267
+    Assumptions.assumeFalse(isXpand());
+
+    CallableStatement stmt = sharedConn.prepareCall("{call useParameterName(?)}");
+    stmt.setInt("a", 1);
+    ResultSet rs = stmt.executeQuery();
+    assertTrue(rs.next());
+    int res = rs.getInt(1);
+    assertEquals(res, 1);
+  }
+
+  @Test
+  public void callWithStrangeParameter() throws SQLException {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+
+    // https://jira.mariadb.org/browse/XPT-267
+    Assumptions.assumeFalse(isXpand());
+
+    try (CallableStatement call = sharedConn.prepareCall("{call withStrangeParameter(?)}")) {
+      double expected = 5.43;
+      call.setDouble("a", expected);
+      try (ResultSet rs = call.executeQuery()) {
+        assertTrue(rs.next());
+        double res = rs.getDouble("b");
+        assertEquals(expected, res, 0);
+        // now fail due to three decimals
+        double tooMuch = 34.987;
+        call.setDouble("a", tooMuch);
+        try (ResultSet rs2 = call.executeQuery()) {
+          assertTrue(rs2.next());
+          assertNotEquals(rs2.getDouble("b"), tooMuch);
+        }
+      }
+    }
+  }
+
+  @Test
+  public void basicProcedure() throws SQLException {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+    // https://jira.mariadb.org/browse/XPT-267
+    Assumptions.assumeFalse(isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS basic_proc");
+    stmt.execute(
+        "CREATE PROCEDURE basic_proc (INOUT t1 INT, IN t2 MEDIUMINT unsigned, OUT t3 DECIMAL(8,3),"
+            + " OUT t4 VARCHAR(20), IN t5 SMALLINT) BEGIN \n"
+            + "set t3 = t1 * t5;\n"
+            + "set t1 = t2 * t1;\n"
+            + "set t4 = 'return data';\n"
+            + "END");
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall("{call basic_proc(?,?,?,?)}")) {
+      ParameterMetaData meta = callableStatement.getParameterMetaData();
+      assertEquals(5, meta.getParameterCount());
+      assertEquals("int", meta.getParameterClassName(1));
+      assertEquals("int", meta.getParameterClassName(2));
+      assertEquals("java.math.BigDecimal", meta.getParameterClassName(3));
+      assertEquals("java.lang.String", meta.getParameterClassName(4));
+      assertEquals("short", meta.getParameterClassName(5));
+      Common.assertThrowsContains(
+          SQLException.class, () -> meta.getParameterClassName(6), "invalid parameter index 6");
+
+      assertEquals("INT", meta.getParameterTypeName(1));
+      assertEquals("MEDIUMINT", meta.getParameterTypeName(2));
+      assertEquals("DECIMAL", meta.getParameterTypeName(3));
+      assertEquals("VARCHAR", meta.getParameterTypeName(4));
+      assertEquals("SMALLINT", meta.getParameterTypeName(5));
+      Common.assertThrowsContains(
+          SQLException.class, () -> meta.getParameterTypeName(0), "invalid parameter index 0");
+
+      assertEquals(Types.INTEGER, meta.getParameterType(1));
+      assertEquals(Types.INTEGER, meta.getParameterType(2));
+      assertEquals(Types.DECIMAL, meta.getParameterType(3));
+      assertEquals(Types.VARCHAR, meta.getParameterType(4));
+      assertEquals(Types.SMALLINT, meta.getParameterType(5));
+      Common.assertThrowsContains(
+          SQLException.class, () -> meta.getParameterType(0), "invalid parameter index 0");
+
+      assertEquals(ParameterMetaData.parameterModeInOut, meta.getParameterMode(1));
+      assertEquals(ParameterMetaData.parameterModeIn, meta.getParameterMode(2));
+      assertEquals(ParameterMetaData.parameterModeOut, meta.getParameterMode(3));
+      assertEquals(ParameterMetaData.parameterModeOut, meta.getParameterMode(4));
+      assertEquals(ParameterMetaData.parameterModeIn, meta.getParameterMode(5));
+      Common.assertThrowsContains(
+          SQLException.class, () -> meta.getParameterMode(10), "invalid parameter index 10");
+
+      assertEquals(10, meta.getPrecision(1));
+      assertEquals(8, meta.getPrecision(3));
+      assertEquals(20, meta.getPrecision(4));
+      assertEquals(5, meta.getPrecision(5));
+      Common.assertThrowsContains(
+          SQLException.class, () -> meta.getPrecision(10), "invalid parameter index 10");
+
+      assertEquals(0, meta.getScale(1));
+      assertEquals(0, meta.getScale(2));
+      assertEquals(3, meta.getScale(3));
+      assertEquals(0, meta.getScale(4));
+      assertEquals(0, meta.getScale(5));
+      Common.assertThrowsContains(
+          SQLException.class, () -> meta.getScale(10), "invalid parameter index 10");
+
+      assertTrue(meta.isSigned(1));
+      assertFalse(meta.isSigned(2));
+
+      assertEquals(ParameterMetaData.parameterNullableUnknown, meta.isNullable(1));
+      assertEquals(ParameterMetaData.parameterNullableUnknown, meta.isNullable(2));
+
+      assertNotNull(meta.unwrap(org.mariadb.jdbc.CallableParameterMetaData.class));
+      assertNotNull(meta.unwrap(ParameterMetaData.class));
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> meta.unwrap(String.class),
+          "The receiver is not a wrapper for java.lang.String");
+      assertTrue(meta.isWrapperFor(org.mariadb.jdbc.CallableParameterMetaData.class));
+      assertTrue(meta.isWrapperFor(ParameterMetaData.class));
+      assertFalse(meta.isWrapperFor(String.class));
+    }
+  }
+
+  @Test
+  public void getParameterTypeProcedure() throws SQLException {
+    // https://jira.mariadb.org/browse/XPT-267
+    Assumptions.assumeFalse(isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS procType");
+    stmt.execute(
+        "CREATE PROCEDURE procType ("
+            + "IN t1 TINYINT, "
+            + "IN t2 SMALLINT, "
+            + "IN t3 MEDIUMINT, "
+            + "IN t4 INT, "
+            + "IN t5 BIGINT, "
+            + "IN t6 DECIMAL(6,3), "
+            + "IN t7 FLOAT, "
+            + "IN t8 DOUBLE, "
+            + "IN t9 BIT, "
+            + "IN t10 CHAR(5), "
+            + "IN t11 VARCHAR(6), "
+            + "IN t12 BINARY(6), "
+            + "IN t13 VARBINARY(6), "
+            + "IN t14 TINYBLOB, "
+            + "IN t15 BLOB, "
+            + "IN t16 MEDIUMBLOB, "
+            + "IN t17 LONGBLOB, "
+            + "IN t18 TINYTEXT, "
+            + "IN t19 TEXT, "
+            + "IN t20 MEDIUMTEXT, "
+            + "IN t21 LONGTEXT, "
+            + "IN t22 ENUM('value1','value2'), "
+            + "IN t23 DATE, "
+            + "IN t24 TIME, "
+            + "IN t25 TIMESTAMP, "
+            + "IN t26 DATETIME, "
+            + "IN t27 YEAR, "
+            + "IN t28 NUMERIC "
+            + ")\n BEGIN \n"
+            + "SELECT 1;\n"
+            + "END");
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall(
+            "{call procType(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}")) {
+      ParameterMetaData meta = callableStatement.getParameterMetaData();
+
+      String[] expectedTypeName =
+          new String[] {
+            "TINYINT",
+            "SMALLINT",
+            "MEDIUMINT",
+            "INT",
+            "BIGINT",
+            "DECIMAL",
+            "FLOAT",
+            "DOUBLE",
+            "BIT",
+            "CHAR",
+            "VARCHAR",
+            "BINARY",
+            "VARBINARY",
+            "TINYBLOB",
+            "BLOB",
+            "MEDIUMBLOB",
+            "LONGBLOB",
+            "TINYTEXT",
+            "TEXT",
+            "MEDIUMTEXT",
+            "LONGTEXT",
+            "ENUM",
+            "DATE",
+            "TIME",
+            "TIMESTAMP",
+            "DATETIME",
+            "YEAR",
+            "DECIMAL"
+          };
+      int[] expectedType =
+          new int[] {
+            Types.TINYINT,
+            Types.SMALLINT,
+            Types.INTEGER,
+            Types.INTEGER,
+            Types.BIGINT,
+            Types.DECIMAL,
+            Types.FLOAT,
+            Types.DOUBLE,
+            Types.BIT,
+            Types.CHAR,
+            Types.VARCHAR,
+            Types.BINARY,
+            Types.VARBINARY,
+            Types.BLOB,
+            Types.BLOB,
+            Types.BLOB,
+            Types.BLOB,
+            Types.VARCHAR,
+            Types.CLOB,
+            Types.CLOB,
+            Types.CLOB,
+            Types.VARCHAR,
+            Types.DATE,
+            Types.TIME,
+            Types.TIMESTAMP,
+            Types.TIMESTAMP,
+            Types.SMALLINT,
+            Types.DECIMAL
+          };
+
+      String[] expectedClass =
+          new String[] {
+            byte.class.getName(),
+            short.class.getName(),
+            int.class.getName(),
+            int.class.getName(),
+            long.class.getName(),
+            BigDecimal.class.getName(),
+            float.class.getName(),
+            double.class.getName(),
+            BitSet.class.getName(),
+            String.class.getName(),
+            String.class.getName(),
+            byte[].class.getName(),
+            byte[].class.getName(),
+            byte[].class.getName(),
+            Blob.class.getName(),
+            Blob.class.getName(),
+            Blob.class.getName(),
+            String.class.getName(),
+            Clob.class.getName(),
+            Clob.class.getName(),
+            Clob.class.getName(),
+            String.class.getName(),
+            Date.class.getName(),
+            Time.class.getName(),
+            Timestamp.class.getName(),
+            Timestamp.class.getName(),
+            short.class.getName(),
+            BigDecimal.class.getName()
+          };
+      for (int i = 1; i < 29; i++) {
+        assertEquals(expectedTypeName[i - 1], meta.getParameterTypeName(i));
+        assertEquals(expectedType[i - 1], meta.getParameterType(i));
+        assertEquals(expectedClass[i - 1], meta.getParameterClassName(i));
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ProcedureTest.java b/src/test/java/org/mariadb/jdbc/integration/ProcedureTest.java
new file mode 100644
index 0000000..53d8568
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ProcedureTest.java
@@ -0,0 +1,1129 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+
+public class ProcedureTest extends Common {
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS procedure_test");
+    stmt.execute("DROP PROCEDURE IF EXISTS multiply_by_2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE procedure_test (t0 int)");
+    stmt.execute("CREATE PROCEDURE multiply_by_2 (INOUT t1 INT) BEGIN \nset t1 = t1 * 2;\nEND");
+  }
+
+  @Test
+  public void settingParameterBeforeOutRegistration() throws SQLException {
+    try (CallableStatement cstmt = sharedConn.prepareCall("{ CALL multiply_by_2(?) }")) {
+      cstmt.setLong(1, 42L);
+      cstmt.registerOutParameter(1, Types.NUMERIC);
+      cstmt.executeQuery();
+      assertEquals(84, cstmt.getLong(1));
+    }
+  }
+
+  @Test
+  public void wrongCall() {
+    Common.assertThrowsContains(
+        SQLException.class, () -> sharedConn.prepareCall("SELECT ?"), "invalid callable syntax");
+  }
+
+  @Test
+  public void prepInsert() throws SQLException {
+    // https://jira.mariadb.org/browse/XPT-267
+    Assumptions.assumeFalse(isXpand());
+
+    Statement st = sharedConn.createStatement();
+    st.execute("DROP PROCEDURE IF EXISTS prep_proc2");
+    st.execute(
+        "CREATE PROCEDURE prep_proc2 (IN t1 INT) BEGIN \n"
+            + "INSERT INTO procedure_test(t0) VALUE (t1);\n"
+            + "END");
+
+    try (PreparedStatement stmt = sharedConn.prepareCall("CALL prep_proc2(?)")) {
+      stmt.setInt(1, 1);
+      stmt.execute();
+    }
+  }
+
+  @Test
+  public void prep() throws SQLException {
+    Statement st = sharedConn.createStatement();
+    st.execute("DROP PROCEDURE IF EXISTS prep_proc");
+    st.execute("CREATE PROCEDURE prep_proc (IN t1 INT) BEGIN \n" + "SELECT t1;\n" + "END");
+
+    try (PreparedStatement stmt = sharedConn.prepareCall("CALL prep_proc(?)")) {
+      assertEquals(ResultSet.TYPE_FORWARD_ONLY, stmt.getResultSetType());
+      assertEquals(ResultSet.CONCUR_READ_ONLY, stmt.getResultSetConcurrency());
+      assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+      assertEquals(sharedConn, stmt.getConnection());
+    }
+
+    try (PreparedStatement stmt =
+        sharedConn.prepareCall(
+            "CALL prep_proc(?)", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
+      assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, stmt.getResultSetType());
+      assertEquals(ResultSet.CONCUR_UPDATABLE, stmt.getResultSetConcurrency());
+      assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+      assertEquals(sharedConn, stmt.getConnection());
+    }
+
+    try (PreparedStatement stmt =
+        sharedConn.prepareCall(
+            "CALL prep_proc(?)",
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE,
+            ResultSet.CLOSE_CURSORS_AT_COMMIT)) {
+      assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, stmt.getResultSetType());
+      assertEquals(ResultSet.CONCUR_UPDATABLE, stmt.getResultSetConcurrency());
+      // not supported
+      assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+      assertEquals(sharedConn, stmt.getConnection());
+    }
+  }
+
+  @Test
+  @SuppressWarnings("deprecated")
+  public void basicProcedure() throws Throwable {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+    // https://jira.mariadb.org/browse/XPT-267
+    Assumptions.assumeFalse(isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS basic_proc");
+    stmt.execute(
+        "CREATE PROCEDURE basic_proc (IN t1 INT, INOUT t2 INT unsigned, OUT t3 INT, IN t4 INT, OUT"
+            + " t5 VARCHAR(20), OUT t6 TIMESTAMP, OUT t7 blob) BEGIN \n"
+            + "SELECT 1;\n"
+            + "set t3 = t1 * t4;\n"
+            + "set t2 = t2 * t1;\n"
+            + "set t5 = 'http://test';\n"
+            + "set t6 = TIMESTAMP('2003-12-31 12:00:00');\n"
+            + "set t7 = 'test';\n"
+            + "END");
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall("{call basic_proc(?,?,?,?,?,?,?)}")) {
+      Common.assertThrowsContains(
+          SQLException.class, () -> callableStatement.getString(1), "No output result");
+      callableStatement.getParameterMetaData();
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class,
+          () -> callableStatement.registerOutParameter(20, JDBCType.INTEGER),
+          "wrong parameter index 20");
+
+      callableStatement.registerOutParameter(2, JDBCType.INTEGER);
+      callableStatement.registerOutParameter(3, JDBCType.INTEGER);
+      callableStatement.registerOutParameter(5, JDBCType.VARCHAR);
+      callableStatement.registerOutParameter(6, JDBCType.TIMESTAMP);
+      callableStatement.registerOutParameter(7, JDBCType.TIMESTAMP);
+      checkResults(callableStatement);
+
+      callableStatement.clearParameters();
+      checkResults(callableStatement);
+
+      ParameterMetaData meta = callableStatement.getParameterMetaData();
+
+      assertEquals("INT", meta.getParameterTypeName(1));
+      assertEquals("VARCHAR", meta.getParameterTypeName(5));
+
+      callableStatement.registerOutParameter(2, Types.INTEGER);
+      callableStatement.registerOutParameter(3, Types.INTEGER);
+      callableStatement.registerOutParameter(5, Types.VARCHAR);
+      callableStatement.registerOutParameter(6, Types.TIMESTAMP);
+      callableStatement.registerOutParameter(7, Types.TIMESTAMP);
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter(2, Types.INTEGER, 10);
+      callableStatement.registerOutParameter(3, Types.INTEGER, 10);
+      callableStatement.registerOutParameter(5, Types.VARCHAR, 10);
+      callableStatement.registerOutParameter(6, Types.TIMESTAMP, 10);
+      callableStatement.registerOutParameter(7, Types.TIMESTAMP, 10);
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter(2, JDBCType.INTEGER, 10);
+      callableStatement.registerOutParameter(3, JDBCType.INTEGER, 10);
+      callableStatement.registerOutParameter(5, JDBCType.VARCHAR, 10);
+      callableStatement.registerOutParameter(6, JDBCType.TIMESTAMP, 10);
+      callableStatement.registerOutParameter(7, JDBCType.TIMESTAMP, 10);
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter(2, Types.INTEGER, "typeName");
+      callableStatement.registerOutParameter(3, Types.INTEGER, "typeName");
+      callableStatement.registerOutParameter(5, Types.VARCHAR, "typeName");
+      callableStatement.registerOutParameter(6, Types.TIMESTAMP, "typeName");
+      callableStatement.registerOutParameter(7, Types.BLOB, "typeName");
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter(2, JDBCType.INTEGER, "typeName");
+      callableStatement.registerOutParameter(3, JDBCType.INTEGER, "typeName");
+      callableStatement.registerOutParameter(5, JDBCType.VARCHAR, "typeName");
+      callableStatement.registerOutParameter(6, JDBCType.TIMESTAMP, "typeName");
+      callableStatement.registerOutParameter(7, JDBCType.BLOB, "typeName");
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter("t2", JDBCType.INTEGER);
+      callableStatement.registerOutParameter("t3", JDBCType.INTEGER);
+      callableStatement.registerOutParameter("t5", JDBCType.VARCHAR);
+      callableStatement.registerOutParameter("t6", JDBCType.TIMESTAMP);
+      callableStatement.registerOutParameter("t7", JDBCType.BLOB);
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter("t2", Types.INTEGER);
+      callableStatement.registerOutParameter("t3", Types.INTEGER);
+      callableStatement.registerOutParameter("t5", Types.VARCHAR);
+      callableStatement.registerOutParameter("t6", Types.TIMESTAMP);
+      callableStatement.registerOutParameter("t7", Types.BLOB);
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter("t2", Types.INTEGER, 10);
+      callableStatement.registerOutParameter("t3", Types.INTEGER, 10);
+      callableStatement.registerOutParameter("t5", Types.VARCHAR, 10);
+      callableStatement.registerOutParameter("t6", Types.TIMESTAMP, 10);
+      callableStatement.registerOutParameter("t7", Types.BLOB, 10);
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter("t2", JDBCType.INTEGER, 10);
+      callableStatement.registerOutParameter("t3", JDBCType.INTEGER, 10);
+      callableStatement.registerOutParameter("t5", JDBCType.VARCHAR, 10);
+      callableStatement.registerOutParameter("t6", JDBCType.TIMESTAMP, 10);
+      callableStatement.registerOutParameter("t7", JDBCType.BLOB, 10);
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter("t2", Types.INTEGER, "typeName");
+      callableStatement.registerOutParameter("t3", Types.INTEGER, "typeName");
+      callableStatement.registerOutParameter("t5", Types.VARCHAR, "typeName");
+      callableStatement.registerOutParameter("t6", Types.TIMESTAMP, "typeName");
+      callableStatement.registerOutParameter("t7", Types.BLOB, "typeName");
+      checkResults(callableStatement);
+
+      callableStatement.registerOutParameter("t2", JDBCType.INTEGER, "typeName");
+      callableStatement.registerOutParameter("t3", JDBCType.INTEGER, "typeName");
+      callableStatement.registerOutParameter("t5", JDBCType.VARCHAR, "typeName");
+      callableStatement.registerOutParameter("t6", JDBCType.TIMESTAMP, "typeName");
+      callableStatement.registerOutParameter("t7", JDBCType.BLOB, "typeName");
+      checkResults(callableStatement);
+
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> callableStatement.registerOutParameter(100, JDBCType.BINARY),
+          "wrong parameter index 100");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> callableStatement.registerOutParameter("unknown", JDBCType.INTEGER),
+          "parameter name unknown not found");
+    }
+  }
+
+  @SuppressWarnings("deprecation")
+  private void checkResults(CallableStatement callableStatement) throws SQLException, IOException {
+    callableStatement.setInt(1, 2);
+    callableStatement.setInt(2, 3);
+    callableStatement.setInt(4, 10);
+    callableStatement.execute();
+
+    assertEquals(6, callableStatement.getInt(2));
+    assertEquals("6", callableStatement.getString(2));
+    assertTrue(callableStatement.getBoolean(2));
+    assertEquals((byte) 6, callableStatement.getByte(2));
+    assertEquals((short) 6, callableStatement.getShort(2));
+    assertEquals(6L, callableStatement.getLong(2));
+    assertEquals(6F, callableStatement.getFloat(2));
+    assertEquals(6D, callableStatement.getDouble(2));
+    assertEquals(6, callableStatement.getBigDecimal(2).intValue());
+    assertEquals(6, callableStatement.getBigDecimal(2, 5).intValue());
+    assertEquals(6L, callableStatement.getObject(2, (Map<String, Class<?>>) null));
+    assertEquals(6L, callableStatement.getObject(2, new HashMap<>()));
+    assertArrayEquals(new byte[] {116, 101, 115, 116}, callableStatement.getBlob(7).getBytes(1, 4));
+    assertArrayEquals(
+        new byte[] {104, 116, 116, 112, 58, 47, 47, 116, 101, 115, 116},
+        callableStatement.getBytes(5));
+    assertEquals("http://test", callableStatement.getClob(5).toString());
+    assertEquals("http://test", callableStatement.getNClob(5).toString());
+    assertEquals("http://test", callableStatement.getURL(5).toString());
+
+    assertEquals("2003-12-31 12:00:00.0", callableStatement.getTimestamp(6).toString());
+    assertEquals(
+        "2003-12-31 12:00:00.0",
+        callableStatement.getTimestamp(6, Calendar.getInstance()).toString());
+    assertEquals("12:00:00", callableStatement.getTime(6).toString());
+    assertEquals("12:00:00", callableStatement.getTime(6, Calendar.getInstance()).toString());
+    assertEquals("2003-12-31", callableStatement.getDate(6).toString());
+    char[] res = new char[4];
+    callableStatement.getCharacterStream(5).read(res);
+    assertEquals("http", new String(res));
+    callableStatement.getNCharacterStream(5).read(res);
+    assertEquals("http", new String(res));
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getBytes(2),
+        "Data type INTEGER cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getDate(2),
+        "Data type INTEGER cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getBytes(2),
+        "Data type INTEGER cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getDate(2, (Calendar) null),
+        "Data type INTEGER cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTime(2),
+        "Data type INTEGER cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTime(2, (Calendar) null),
+        "Data type INTEGER cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTimestamp(2),
+        "Data type INTEGER cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTimestamp(2, (Calendar) null),
+        "Data type INTEGER cannot be decoded as Timestamp");
+    assertEquals(6L, callableStatement.getObject(2));
+    Map<String, Class<?>> map = new HashMap<>();
+    map.put("f", Integer.class);
+    Common.assertThrowsContains(
+        SQLFeatureNotSupportedException.class,
+        () -> callableStatement.getObject(2, map),
+        " Method ResultSet.getObject(int columnIndex, Map<String, Class<?>> map) not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getRef(2),
+        "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getBlob(2),
+        "Data type INTEGER cannot be decoded as Blob");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getClob(2),
+        "Data type INTEGER cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLFeatureNotSupportedException.class,
+        () -> callableStatement.getArray(2),
+        "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> callableStatement.getURL(2), "Could not parse '6' as URL");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getNClob(2),
+        "Data type INTEGER cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLFeatureNotSupportedException.class,
+        () -> callableStatement.getSQLXML(2),
+        "SQLXML are not supported");
+    assertEquals("6", callableStatement.getNString(2));
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> callableStatement.getNCharacterStream(2),
+        "Data type INTEGER cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> callableStatement.getCharacterStream(2),
+        "Data type INTEGER cannot be decoded as Reader");
+    assertEquals("6", callableStatement.getObject(2, String.class));
+    Common.assertThrowsContains(
+        SQLException.class, () -> callableStatement.getRowId(2), "RowId are not supported");
+
+    assertEquals(6, callableStatement.getInt("t2"));
+    assertEquals("6", callableStatement.getString("t2"));
+    assertTrue(callableStatement.getBoolean("t2"));
+    assertEquals((byte) 6, callableStatement.getByte("t2"));
+    assertEquals((short) 6, callableStatement.getShort("t2"));
+    assertEquals(6L, callableStatement.getLong("t2"));
+    assertEquals(6F, callableStatement.getFloat("t2"));
+    assertEquals(6D, callableStatement.getDouble("t2"));
+    assertEquals(6, callableStatement.getBigDecimal("t2").intValue());
+    assertEquals(6L, callableStatement.getObject("t2", (Map<String, Class<?>>) null));
+    assertEquals(6L, callableStatement.getObject("t2", new HashMap<>()));
+    assertArrayEquals(
+        new byte[] {116, 101, 115, 116}, callableStatement.getBlob("t7").getBytes(1, 4));
+    assertArrayEquals(
+        new byte[] {104, 116, 116, 112, 58, 47, 47, 116, 101, 115, 116},
+        callableStatement.getBytes("t5"));
+    assertEquals("http://test", callableStatement.getClob("t5").toString());
+    assertEquals("http://test", callableStatement.getNClob("t5").toString());
+    assertEquals("http://test", callableStatement.getURL("t5").toString());
+    callableStatement.getCharacterStream("t5").read(res);
+    assertEquals("http", new String(res));
+    callableStatement.getNCharacterStream("t5").read(res);
+    assertEquals("http", new String(res));
+
+    assertEquals("2003-12-31 12:00:00.0", callableStatement.getTimestamp("t6").toString());
+    assertEquals(
+        "2003-12-31 12:00:00.0",
+        callableStatement.getTimestamp("t6", Calendar.getInstance()).toString());
+    assertEquals("12:00:00", callableStatement.getTime("t6").toString());
+    assertEquals("12:00:00", callableStatement.getTime("t6", Calendar.getInstance()).toString());
+    assertEquals("2003-12-31", callableStatement.getDate("t6").toString());
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getBytes(null),
+        "parameter name cannot be null");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getBytes("t2"),
+        "Data type INTEGER cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLException.class, () -> callableStatement.getRowId("t2"), "RowId are not supported");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getDate("t2"),
+        "Data type INTEGER cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getDate("t2", (Calendar) null),
+        "Data type INTEGER cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTime("t2"),
+        "Data type INTEGER cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTime("t2", (Calendar) null),
+        "Data type INTEGER cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTimestamp("t2"),
+        "Data type INTEGER cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getTimestamp("t2", (Calendar) null),
+        "Data type INTEGER cannot be decoded as Timestamp");
+    assertEquals(6L, callableStatement.getObject("t2"));
+    Common.assertThrowsContains(
+        SQLFeatureNotSupportedException.class,
+        () -> callableStatement.getObject("t2", map),
+        " Method ResultSet.getObject(int columnIndex, Map<String, Class<?>> map) not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getRef("t2"),
+        "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getBlob("t2"),
+        "Data type INTEGER cannot be decoded as Blob");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getClob("t2"),
+        "Data type INTEGER cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLFeatureNotSupportedException.class,
+        () -> callableStatement.getArray("t2"),
+        "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> callableStatement.getURL("t2"), "Could not parse '6' as URL");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> callableStatement.getNClob("t2"),
+        "Data type INTEGER cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLFeatureNotSupportedException.class,
+        () -> callableStatement.getSQLXML("t2"),
+        "SQLXML are not supported");
+    assertEquals("6", callableStatement.getNString("t2"));
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> callableStatement.getNCharacterStream("t2"),
+        "Data type INTEGER cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> callableStatement.getCharacterStream("t2"),
+        "Data type INTEGER cannot be decoded as Reader");
+    assertEquals("6", callableStatement.getObject("t2", String.class));
+
+    assertFalse(callableStatement.wasNull());
+    assertEquals(20, callableStatement.getInt(3));
+    assertFalse(callableStatement.wasNull());
+    Common.assertThrowsContains(
+        SQLException.class, () -> callableStatement.getInt(-1), "wrong index");
+
+    Common.assertThrowsContains(
+        SQLException.class, () -> callableStatement.getInt(4), "index 4 not declared as output");
+  }
+
+  @Test
+  public void setProcedureTest() throws Exception {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+
+    // https://jira.mariadb.org/browse/XPT-268
+    Assumptions.assumeFalse(isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS basic_proc");
+    stmt.execute(
+        "CREATE PROCEDURE basic_proc (IN t1 VARCHAR(20), INOUT t2 VARCHAR(20)) BEGIN \n"
+            + "set t2 = CONCAT(t1, t2);\n"
+            + "END");
+    try (CallableStatement callableStatement = sharedConn.prepareCall("{call basic_proc(?,?)}")) {
+      callableStatement.registerOutParameter(2, JDBCType.VARCHAR);
+      callableStatement.setString(1, "a");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("ab", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNString(1, "a");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("ab", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setURL(1, new URL("http://a"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("http://ab", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNull(1, Types.VARCHAR);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+      assertTrue(callableStatement.wasNull());
+
+      reset(callableStatement);
+      callableStatement.setNull(1, Types.VARCHAR, "sometype");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+      assertTrue(callableStatement.wasNull());
+
+      reset(callableStatement);
+      callableStatement.setBoolean(1, true);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("1b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setByte(1, (byte) 'a');
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("97b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setShort(1, (short) 6);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setInt(1, 6);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setLong(1, 6L);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setFloat(1, 6F);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setDouble(1, 6D);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBigDecimal(1, BigDecimal.ONE);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("1b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setTimestamp(1, new Timestamp(0));
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTimestamp(2);
+
+      reset(callableStatement);
+      callableStatement.setTimestamp(1, new Timestamp(0), Calendar.getInstance());
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTimestamp(2);
+
+      reset(callableStatement);
+      callableStatement.setBytes(1, new byte[] {(byte) 'a', (byte) 0x45});
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("aEc", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBlob(1, new MariaDbBlob("0123".getBytes(), 1, 2));
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("12c", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBlob(1, new ByteArrayInputStream("eef".getBytes()));
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("eefc", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setDate(1, new Date(0));
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getDate(2);
+
+      reset(callableStatement);
+      callableStatement.setDate(1, new Date(0), Calendar.getInstance());
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getDate(2, Calendar.getInstance());
+
+      reset(callableStatement);
+      callableStatement.setTime(1, new Time(0));
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTime(2);
+
+      reset(callableStatement);
+      callableStatement.setTime(1, new Time(0), Calendar.getInstance());
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTime(2);
+
+      reset(callableStatement);
+      callableStatement.setAsciiStream(1, new ByteArrayInputStream("dbc".getBytes()));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("dbcb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setAsciiStream(1, new ByteArrayInputStream("cbc".getBytes()), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("cbb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBinaryStream(1, new ByteArrayInputStream("bef".getBytes()));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("befb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBinaryStream(1, new ByteArrayInputStream("aef".getBytes()), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("aeb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(1, new ByteArrayInputStream("saf".getBytes()));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("safb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          1, new ByteArrayInputStream("sbf".getBytes()), Types.LONGVARBINARY);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sbfb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          1, new ByteArrayInputStream("scf".getBytes()), JDBCType.LONGVARBINARY);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("scfb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(1, null);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          1, new ByteArrayInputStream("sdf".getBytes()), Types.LONGVARBINARY, 10);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sdfb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          1, new ByteArrayInputStream("sea".getBytes()), JDBCType.LONGVARBINARY, 10);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seab", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setCharacterStream(1, new StringReader("seb"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sebb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setClob(1, new MariaDbClob("sec".getBytes(), 0, 16));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("secb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setClob(1, new StringReader("sed"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sedb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setClob(1, new StringReader("sef"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNClob(1, new MariaDbClob("seg".getBytes(), 0, 16));
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("segc", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNClob(1, new StringReader("seh"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sehb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNClob(1, new StringReader("sei"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setCharacterStream(1, new StringReader("sej"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNCharacterStream(1, new StringReader("seh"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sehb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNCharacterStream(1, new StringReader("sek"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setDate(1, new Date(0));
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getDate(2);
+
+      reset(callableStatement);
+      callableStatement.setDate(1, new Date(0), Calendar.getInstance());
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getDate(2, Calendar.getInstance());
+
+      reset(callableStatement);
+      callableStatement.setNull(1, Types.BINARY);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNull(1, Types.BINARY, "ttt");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+
+      // with named params
+
+      callableStatement.registerOutParameter(2, JDBCType.VARCHAR);
+      callableStatement.setString("t1", "a");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("ab", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNString("t1", "a");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("ab", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setURL("t1", new URL("http://a"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("http://ab", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNull("t1", Types.VARCHAR);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+      assertTrue(callableStatement.wasNull());
+
+      reset(callableStatement);
+      callableStatement.setNull("t1", Types.VARCHAR, "sometype");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+      assertTrue(callableStatement.wasNull());
+
+      reset(callableStatement);
+      callableStatement.setBoolean("t1", true);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("1b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setByte("t1", (byte) 'a');
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("97b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setShort("t1", (short) 6);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setInt("t1", 6);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setLong("t1", 6L);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setFloat("t1", 6F);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setDouble("t1", 6D);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("6b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBigDecimal("t1", BigDecimal.ONE);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("1b", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setTimestamp("t1", new Timestamp(0));
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTimestamp("t2");
+
+      reset(callableStatement);
+      callableStatement.setTimestamp("t1", new Timestamp(0), Calendar.getInstance());
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTimestamp("t2", Calendar.getInstance());
+
+      reset(callableStatement);
+      callableStatement.setBytes("t1", new byte[] {(byte) 'a', (byte) 0x45});
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("aEc", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBlob("t1", new MariaDbBlob("0123".getBytes(), 1, 2));
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("12c", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBlob("t1", new ByteArrayInputStream("sef".getBytes()));
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("sefc", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBlob("t1", new ByteArrayInputStream("sef".getBytes()), 2);
+      callableStatement.setString(2, "c");
+      callableStatement.execute();
+      assertEquals("sec", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setDate("t1", new Date(0));
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getDate("t2");
+
+      reset(callableStatement);
+      callableStatement.setDate("t1", new Date(0), Calendar.getInstance());
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getDate("t2", Calendar.getInstance());
+
+      reset(callableStatement);
+      callableStatement.setTime("t1", new Time(0));
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTime("t2");
+
+      reset(callableStatement);
+      callableStatement.setTime("t1", new Time(0), Calendar.getInstance());
+      callableStatement.setString(2, "");
+      callableStatement.execute();
+      callableStatement.getTime("t2", Calendar.getInstance());
+
+      reset(callableStatement);
+      callableStatement.setAsciiStream("t1", new ByteArrayInputStream("abc".getBytes()));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("abcb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setAsciiStream("t1", new ByteArrayInputStream("abc".getBytes()), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("abcb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setAsciiStream("t1", new ByteArrayInputStream("abc".getBytes()), 2L);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("abb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBinaryStream("t1", new ByteArrayInputStream("sef".getBytes()));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBinaryStream("t1", new ByteArrayInputStream("sef".getBytes()), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setBinaryStream("t1", new ByteArrayInputStream("sef".getBytes()), 2L);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject("t1", new ByteArrayInputStream("sef".getBytes()));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          "t1", new ByteArrayInputStream("sef".getBytes()), Types.LONGVARBINARY);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          "t1", new ByteArrayInputStream("sef".getBytes()), JDBCType.LONGVARBINARY);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          "t1", new ByteArrayInputStream("sef".getBytes()), Types.LONGVARBINARY, 10);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setObject(
+          "t1", new ByteArrayInputStream("sef".getBytes()), JDBCType.LONGVARBINARY, 10);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setCharacterStream("t1", new StringReader("sef"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setCharacterStream("t1", new StringReader("sef"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setCharacterStream("t1", new StringReader("sef"), 2L);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNCharacterStream("t1", new StringReader("sef"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNCharacterStream("t1", new StringReader("sef"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setDate("t1", new Date(0));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+
+      reset(callableStatement);
+      callableStatement.setNull("t1", Types.BINARY);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNull("t1", Types.BINARY, "ttt");
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertNull(callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setClob("t1", new MariaDbClob("sef".getBytes(), 0, 16));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setClob("t1", new StringReader("sef"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setClob("t1", new StringReader("sef"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNClob("t1", new MariaDbClob("sef".getBytes(), 0, 16));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNClob("t1", new StringReader("sef"));
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("sefb", callableStatement.getString(2));
+
+      reset(callableStatement);
+      callableStatement.setNClob("t1", new StringReader("sef"), 2);
+      callableStatement.setString(2, "b");
+      callableStatement.execute();
+      assertEquals("seb", callableStatement.getString(2));
+
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> callableStatement.setRowId(1, null),
+          "RowId parameter are not supported");
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> callableStatement.setRowId("t1", null),
+          "RowId parameter are not supported");
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> callableStatement.setSQLXML(1, null),
+          "SQLXML parameter are not supported");
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> callableStatement.setSQLXML("t1", null),
+          "SQLXML parameter are not supported");
+    }
+  }
+
+  private void reset(CallableStatement callableStatement) throws SQLException {
+    callableStatement.registerOutParameter(2, JDBCType.VARCHAR);
+    callableStatement.setString(1, "a");
+    callableStatement.setString(2, "b");
+    callableStatement.execute();
+    assertEquals("ab", callableStatement.getString(2));
+  }
+
+  @Test
+  public void procedureToString() throws SQLException {
+    try (CallableStatement callableStatement =
+        sharedConn.prepareCall("{call basic_proc(?,?,?,?,?,?,?)}")) {
+
+      assertEquals(
+          "ProcedureStatement{sql:'call basic_proc(?,?,?,?,?,?,?)', parameters:[]}",
+          callableStatement.toString());
+      callableStatement.registerOutParameter(2, JDBCType.INTEGER);
+      callableStatement.registerOutParameter(3, JDBCType.INTEGER);
+      callableStatement.registerOutParameter(5, JDBCType.VARCHAR);
+      assertEquals(
+          "ProcedureStatement{sql:'call basic_proc(?,?,?,?,?,?,?)',"
+              + " parameters:[null,<OUT>null,<OUT>null,null,<OUT>null]}",
+          callableStatement.toString());
+      callableStatement.setBytes(2, new byte[] {(byte) 'a', (byte) 'b'});
+      callableStatement.setLong(1, 10L);
+      assertEquals(
+          "ProcedureStatement{sql:'call basic_proc(?,?,?,?,?,?,?)', parameters:[10,<OUT>_binary"
+              + " 'ab',<OUT>null,null,<OUT>null]}",
+          callableStatement.toString());
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/ResultSetTest.java b/src/test/java/org/mariadb/jdbc/integration/ResultSetTest.java
new file mode 100644
index 0000000..0931148
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/ResultSetTest.java
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.*;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+
+public class ResultSetTest extends Common {
+
+  private final Class<? extends java.lang.Exception> ns = SQLFeatureNotSupportedException.class;
+
+  @AfterAll
+  public static void after2() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE IF EXISTS resultsettest");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    after2();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS resultsettest");
+    stmt.execute("CREATE TABLE resultsettest (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("INSERT INTO resultsettest(t2) values (1),(2),(3),(4),(5),(6),(7),(8)");
+  }
+
+  @Test
+  public void nonUpdatableFields() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION");
+    ResultSet rs = stmt.executeQuery("SELECT * FROM resultsettest");
+    Assertions.assertNull(rs.getWarnings());
+    rs.next();
+    Common.assertThrowsContains(ns, () -> rs.updateArray(1, null), "Array are not supported");
+    String NOT_SUPPORTED = "Not supported when using CONCUR_READ_ONLY concurrency";
+    Common.assertThrowsContains(ns, () -> rs.updateNull(1), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBoolean(1, true), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateByte(1, (byte) 0x00), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateShort(1, (short) 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateInt(1, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateLong(1, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateFloat(1, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDouble(1, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBigDecimal(1, BigDecimal.ZERO), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateString(1, ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNString(1, ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBytes(1, new byte[0]), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDate(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTime(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTimestamp(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob(1, (Blob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob(1, (Clob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob(1, (InputStream) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob(1, (Reader) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob(1, (NClob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob(1, (Reader) null), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, () -> rs.updateArray("t1", null), "Array are not supported");
+
+    Common.assertThrowsContains(ns, () -> rs.updateNull("t1"), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBoolean("t1", true), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateByte("t1", (byte) 0x00), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateShort("t1", (short) 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateInt("t1", 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateLong("t1", 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateFloat("t1", 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDouble("t1", 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(
+        ns, () -> rs.updateBigDecimal("t1", BigDecimal.ZERO), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateString("t1", ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNString("t1", ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBytes("t1", new byte[0]), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDate("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTime("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTimestamp("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, () -> rs.updateBlob("t1", (Blob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob("t1", (InputStream) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob("t1", (Clob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob("t1", (Reader) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob("t1", (NClob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob("t1", (Reader) null), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, rs::insertRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::updateRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::deleteRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::refreshRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::cancelRowUpdates, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::moveToInsertRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::moveToCurrentRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::rowUpdated, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::rowInserted, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::rowDeleted, NOT_SUPPORTED);
+
+    Common.assertThrowsContains(
+        ns, () -> rs.updateRef(1, null), "Method ResultSet.updateRef not supported");
+    Common.assertThrowsContains(
+        ns, () -> rs.updateRef("t1", null), "Method ResultSet.updateRef not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateArray(1, null), "Array are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateArray("t1", null), "Array are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateRowId(1, null), "RowId are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateRowId("t1", null), "RowId are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateSQLXML(1, null), "SQLXML not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateSQLXML("t1", null), "SQLXML not supported");
+
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream("t1", null, 0), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null, null), NOT_SUPPORTED);
+    sharedConn.rollback();
+  }
+
+  @Test
+  public void notSupported() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION");
+    ResultSet rs = stmt.executeQuery("SELECT * FROM resultsettest");
+    Common.assertThrowsContains(ns, () -> rs.getRowId(1), "RowId are not supported");
+    Common.assertThrowsContains(ns, () -> rs.getRowId("t1"), "RowId are not supported");
+    Map<String, Class<?>> map = new HashMap<>();
+    map.put("f", Integer.class);
+    Common.assertThrowsContains(
+        ns,
+        () -> rs.getObject(1, map),
+        "Method ResultSet.getObject(int columnIndex, Map<String, Class<?>> map) not supported");
+    Common.assertThrowsContains(
+        ns,
+        () -> rs.getObject("t1", map),
+        "Method ResultSet.getObject(String columnLabel, Map<String, Class<?>> map) not supported");
+    Common.assertThrowsContains(ns, rs::getCursorName, "Cursors are not supported");
+    sharedConn.rollback();
+  }
+
+  @Test
+  public void staticMethod() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION");
+    ResultSet rs = stmt.executeQuery("SELECT * FROM resultsettest");
+    Assertions.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, rs.getHoldability());
+    rs.unwrap(java.sql.ResultSet.class);
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.unwrap(String.class),
+        "The receiver is not a wrapper for java.lang.String");
+    sharedConn.rollback();
+  }
+
+  @Test
+  public void wrongIndex() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION");
+    ResultSet rs = stmt.executeQuery("SELECT * FROM resultsettest");
+    rs.next();
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(-1),
+        "Wrong index position. Is -1 but must be in 1-2 range");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(10),
+        "Wrong index position. Is 10 but must be in 1-2 range");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.findColumn(null), "null is not a valid label value");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.findColumn("yy"),
+        "Unknown label 'yy'. Possible value [resultsettest.t1, t1, resultsettest.t2, t2]");
+    sharedConn.rollback();
+  }
+
+  @Test
+  public void isBeforeFirstFetchTest() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION");
+    stmt.setFetchSize(1);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM resultsettest");
+    assertTrue(rs.isBeforeFirst());
+    while (rs.next()) {
+      assertFalse(rs.isBeforeFirst());
+    }
+    assertFalse(rs.isBeforeFirst());
+    rs.close();
+    Common.assertThrowsContains(
+        SQLException.class, rs::isBeforeFirst, "Operation not permit on a closed resultSet");
+    sharedConn.rollback();
+  }
+
+  @Test
+  public void testAliases() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION");
+    ResultSet rs =
+        stmt.executeQuery("SELECT t1 as t1alias, t2 as t2alias FROM resultsettest as tablealias");
+    rs.next();
+    assertEquals(1, rs.getInt(1));
+    assertEquals(1, rs.getInt("t1alias"));
+    assertEquals(1, rs.getInt("tablealias.t1alias"));
+    assertEquals(1, rs.getInt(1));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertEquals(1, rs.getInt("tablealias.t2alias"));
+
+    rs = stmt.executeQuery("SELECT t1 as t1alias, t2 as t2alias FROM resultsettest");
+    rs.next();
+    assertEquals(1, rs.getInt(1));
+    assertEquals(1, rs.getInt("t1alias"));
+    assertEquals(1, rs.getInt("resultsettest.t1alias"));
+    assertEquals(1, rs.getInt(1));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertEquals(1, rs.getInt("resultsettest.t2alias"));
+
+    rs = stmt.executeQuery("SELECT t1, t2 FROM resultsettest");
+    rs.next();
+    assertEquals(1, rs.getInt(1));
+    assertEquals(1, rs.getInt("t1"));
+    assertEquals(1, rs.getInt("resultsettest.t1"));
+    assertEquals(1, rs.getInt(1));
+    assertEquals(1, rs.getInt("t2"));
+    assertEquals(1, rs.getInt("resultsettest.t2"));
+    sharedConn.rollback();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/Sha256AuthenticationTest.java b/src/test/java/org/mariadb/jdbc/integration/Sha256AuthenticationTest.java
new file mode 100644
index 0000000..a45eca2
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/Sha256AuthenticationTest.java
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.*;
+import org.junit.jupiter.api.*;
+
+public class Sha256AuthenticationTest extends Common {
+
+  private static String rsaPublicKey;
+
+  private static void dropUserWithoutError(org.mariadb.jdbc.Statement stmt, String user) {
+    try {
+      stmt.execute("DROP USER IF EXISTS " + user);
+    } catch (SQLException e) {
+      // eat
+    }
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    if (sharedConn != null) {
+      org.mariadb.jdbc.Statement stmt = sharedConn.createStatement();
+      dropUserWithoutError(stmt, "'cachingSha256User'@'%'");
+      dropUserWithoutError(stmt, "'cachingSha256User2'@'%'");
+      dropUserWithoutError(stmt, "'cachingSha256User3'@'%'");
+      dropUserWithoutError(stmt, "'cachingSha256User4'@'%'");
+    }
+    // reason is that after nativePassword test, it sometime always return wrong authentication id
+    // not cached
+    // !? strange, but mysql server error.
+    if (haveSsl() && !isMariaDBServer() && minVersion(8, 0, 0)) {
+      try (Connection con = createCon("sslMode=trust")) {
+        con.createStatement().execute("DO 1");
+      }
+    }
+  }
+
+  @BeforeAll
+  public static void init() throws Exception {
+    Assumptions.assumeTrue(!isMariaDBServer() && minVersion(8, 0, 0));
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    rsaPublicKey = checkFileExists(System.getProperty("rsaPublicKey"));
+    if (rsaPublicKey == null) {
+      ResultSet rs = stmt.executeQuery("SELECT @@caching_sha2_password_public_key_path, @@datadir");
+      rs.next();
+      rsaPublicKey = checkFileExists(rs.getString(1));
+
+      if (rsaPublicKey == null) {
+        rsaPublicKey = checkFileExists(rs.getString(2) + rs.getString(1));
+        if (rsaPublicKey == null) {
+          rsaPublicKey = checkFileExists(System.getenv("TEST_DB_RSA_PUBLIC_KEY"));
+          if (rsaPublicKey == null && System.getenv("TEST_DB_RSA_PUBLIC_KEY") != null) {
+            rsaPublicKey = checkFileExists(System.getenv("TEST_DB_RSA_PUBLIC_KEY"));
+          }
+        }
+      }
+    }
+    if (rsaPublicKey == null) {
+      rsaPublicKey = checkFileExists("../../ssl/public.key");
+    }
+
+    if (rsaPublicKey == null) {
+      ResultSet rs = stmt.executeQuery("SHOW STATUS like 'Caching_sha2_password_rsa_public_key'");
+      rs.next();
+      rsaPublicKey = rs.getString(2);
+      if ("".equals(rsaPublicKey)) rsaPublicKey = null;
+      if (rsaPublicKey != null) {
+        System.out.println(
+            "rsaPublicKey set from @@Caching_sha2_password_rsa_public_key:" + rsaPublicKey);
+      }
+    }
+
+    stmt.execute(
+        "CREATE USER 'cachingSha256User'@'%' IDENTIFIED WITH caching_sha2_password BY"
+            + " '!Passw0rd3Works'");
+    stmt.execute(
+        "CREATE USER 'cachingSha256User2'@'%' IDENTIFIED WITH caching_sha2_password BY ''");
+    stmt.execute(
+        "CREATE USER 'cachingSha256User3'@'%' IDENTIFIED WITH caching_sha2_password BY"
+            + " '!Passw0rd3Works'");
+    stmt.execute(
+        "CREATE USER 'cachingSha256User4'@'%' IDENTIFIED WITH caching_sha2_password BY"
+            + " '!Passw0rd3Works'");
+    stmt.execute("GRANT ALL PRIVILEGES ON *.* TO 'cachingSha256User'@'%'");
+    stmt.execute("GRANT ALL PRIVILEGES ON *.* TO 'cachingSha256User2'@'%'");
+    stmt.execute("GRANT ALL PRIVILEGES ON *.* TO 'cachingSha256User3'@'%'");
+    stmt.execute("GRANT ALL PRIVILEGES ON *.* TO 'cachingSha256User4'@'%'");
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES");
+  }
+
+  private static String checkFileExists(String path) throws IOException {
+    if (path == null) return null;
+    System.out.println("check path:" + path);
+    File f = new File(path);
+    if (f.exists()) {
+      System.out.println("path exist :" + path);
+      return f.getCanonicalPath().replace("\\", "/");
+    }
+    return null;
+  }
+
+  @Test
+  public void nativePassword() throws Exception {
+    Assumptions.assumeTrue(haveSsl());
+    Assumptions.assumeTrue(
+        !isWindows() && !isMariaDBServer() && rsaPublicKey != null && minVersion(8, 0, 0));
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("DROP USER tmpUser@'%'");
+    } catch (SQLException e) {
+      // eat
+    }
+
+    stmt.execute(
+        "CREATE USER tmpUser@'%' IDENTIFIED WITH mysql_native_password BY '!Passw0rd3Works'");
+    stmt.execute("grant all on `" + sharedConn.getCatalog() + "`.* TO tmpUser@'%'");
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    stmt.execute("FLUSH PRIVILEGES"); // reset cache
+    try (Connection con = createCon("user=tmpUser&password=!Passw0rd3Works")) {
+      con.isValid(1);
+    }
+    try {
+      stmt.execute("DROP USER tmpUser@'%' ");
+    } catch (SQLException e) {
+      // eat
+    }
+  }
+
+  @Test
+  public void cachingSha256Empty() throws Exception {
+    Assumptions.assumeTrue(
+        !isWindows() && !isMariaDBServer() && rsaPublicKey != null && minVersion(8, 0, 0));
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !minVersion(8, 0, 31));
+    sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
+    try (Connection con = createCon("user=cachingSha256User2&allowPublicKeyRetrieval&password=")) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void wrongRsaPath() throws Exception {
+    Assumptions.assumeTrue(
+        !isWindows() && !isMariaDBServer() && rsaPublicKey != null && minVersion(8, 0, 0));
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
+    File tempFile = File.createTempFile("log", ".tmp");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () ->
+            createCon(
+                "user=cachingSha256User4&serverRsaPublicKeyFile="
+                    + tempFile.getPath()
+                    + "2&password=!Passw0rd3Works"),
+        "Could not read server RSA public key from file");
+  }
+
+  @Test
+  public void cachingSha256Allow() throws Exception {
+    Assumptions.assumeTrue(!isMariaDBServer() && rsaPublicKey != null && minVersion(8, 0, 0));
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !minVersion(8, 0, 31));
+    sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
+    try (Connection con =
+        createCon("user=cachingSha256User3&allowPublicKeyRetrieval&password=!Passw0rd3Works")) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void cachingSha256PluginTest() throws Exception {
+    Assumptions.assumeTrue(!isMariaDBServer() && rsaPublicKey != null && minVersion(8, 0, 0));
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
+
+    try (Connection con =
+        createCon(
+            "user=cachingSha256User&password=!Passw0rd3Works&serverRsaPublicKeyFile="
+                + rsaPublicKey)) {
+      con.isValid(1);
+    }
+
+    try (Connection con =
+        createCon("user=cachingSha256User&password=!Passw0rd3Works&allowPublicKeyRetrieval")) {
+      con.isValid(1);
+    }
+
+    Assumptions.assumeTrue(haveSsl());
+    try (Connection con =
+        createCon("user=cachingSha256User&password=!Passw0rd3Works&sslMode=trust")) {
+      con.isValid(1);
+    }
+
+    try (Connection con =
+        createCon("user=cachingSha256User&password=!Passw0rd3Works&allowPublicKeyRetrieval")) {
+      con.isValid(1);
+    }
+
+    try (Connection con =
+        createCon(
+            "user=cachingSha256User&password=!Passw0rd3Works&serverRsaPublicKeyFile="
+                + rsaPublicKey)) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void cachingSha256PluginTestWithoutServerRsaKey() throws Exception {
+    Assumptions.assumeTrue(!isWindows() && minVersion(8, 0, 0));
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !minVersion(8, 0, 31));
+    sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
+    try (Connection con =
+        createCon("user=cachingSha256User&password=!Passw0rd3Works&allowPublicKeyRetrieval")) {
+      con.isValid(1);
+    }
+  }
+
+  @Test
+  public void cachingSha256PluginTestException() throws Exception {
+    Assumptions.assumeTrue(!isMariaDBServer() && minVersion(8, 0, 0));
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
+    sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> createCon("user=cachingSha256User&password=!Passw0rd3Works"),
+        "RSA public key is not available client side");
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/SslTest.java b/src/test/java/org/mariadb/jdbc/integration/SslTest.java
new file mode 100644
index 0000000..5d3e892
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/SslTest.java
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.nio.file.Paths;
+import java.security.NoSuchAlgorithmException;
+import java.sql.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import javax.net.ssl.SSLContext;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.tools.TcpProxy;
+
+@DisplayName("SSL tests")
+public class SslTest extends Common {
+  private static Integer sslPort;
+  private static final String baseOptions = "&user=serverAuthUser&password=!Passw0rd3Works";
+  private static final String baseMutualOptions = "&user=mutualAuthUser&password=!Passw0rd3Works";
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("DROP USER serverAuthUser");
+    } catch (SQLException e) {
+      // eat
+    }
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Assumptions.assumeTrue(haveSsl());
+    createSslUser("serverAuthUser", "REQUIRE SSL");
+    createSslUser("mutualAuthUser", "REQUIRE X509");
+
+    Statement stmt = sharedConn.createStatement();
+    // mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
+    Assumptions.assumeTrue(isMariaDBServer() || (!isMariaDBServer() && !exactVersion(8, 0, 31)));
+    stmt.execute("FLUSH PRIVILEGES");
+    sslPort =
+        System.getenv("TEST_MAXSCALE_TLS_PORT") == null
+                || System.getenv("TEST_MAXSCALE_TLS_PORT").isEmpty()
+            ? null
+            : Integer.valueOf(System.getenv("TEST_MAXSCALE_TLS_PORT"));
+  }
+
+  private static void createSslUser(String user, String requirement) throws SQLException {
+    boolean useOldNotation =
+        (!isMariaDBServer() || !minVersion(10, 2, 0))
+            && (isMariaDBServer() || !minVersion(8, 0, 0));
+    Statement stmt = sharedConn.createStatement();
+    if (useOldNotation) {
+      stmt.execute("CREATE USER IF NOT EXISTS '" + user + "'@'%' " + requirement);
+      stmt.execute(
+          "GRANT SELECT ON *.* TO '"
+              + user
+              + "'@'%' IDENTIFIED BY '!Passw0rd3Works' "
+              + requirement);
+    } else {
+      if (!isMariaDBServer() && minVersion(8, 0, 0)) {
+        stmt.execute(
+            "CREATE USER IF NOT EXISTS '"
+                + user
+                + "'@'%' IDENTIFIED WITH mysql_native_password BY '!Passw0rd3Works' "
+                + requirement);
+      } else {
+        stmt.execute(
+            "CREATE USER IF NOT EXISTS '"
+                + user
+                + "'@'%' IDENTIFIED BY '!Passw0rd3Works' "
+                + requirement);
+      }
+      stmt.execute("GRANT SELECT ON " + sharedConn.getCatalog() + ".* TO '" + user + "'@'%' ");
+    }
+  }
+
+  private String getSslVersion(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    ResultSet rs = stmt.executeQuery("show STATUS  LIKE 'Ssl_version'");
+    if (rs.next()) {
+      return rs.getString(2);
+    }
+    return null;
+  }
+
+  @Test
+  public void simpleSsl() throws SQLException {
+    try (Connection con = createCon("sslMode=trust", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+    try (Connection con = createCon("sslMode=trust&useReadAheadInput=false", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+  }
+
+  @Test
+  public void mandatorySsl() throws SQLException {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try (Connection con = createCon(baseOptions + "&sslMode=trust", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+    assertThrows(SQLException.class, () -> createCon(baseOptions + "&sslMode=disable"));
+    assertThrows(
+        SQLInvalidAuthorizationSpecException.class,
+        () -> createCon(baseMutualOptions + "&sslMode=trust", sslPort));
+  }
+
+  @Test
+  public void enabledSslProtocolSuites() throws SQLException {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try {
+      List<String> protocols =
+          Arrays.asList(SSLContext.getDefault().getSupportedSSLParameters().getProtocols());
+      Assumptions.assumeTrue(protocols.contains("TLSv1.3") && protocols.contains("TLSv1.2"));
+    } catch (NoSuchAlgorithmException e) {
+      // eat
+    }
+    try (Connection con =
+        createCon(
+            baseOptions + "&sslMode=trust&enabledSslProtocolSuites=TLSv1.2,TLSv1.3", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+    Common.assertThrowsContains(
+        SQLNonTransientConnectionException.class,
+        () ->
+            createCon(baseMutualOptions + "&sslMode=trust&enabledSslProtocolSuites=SSLv3", sslPort),
+        "No appropriate protocol");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () ->
+            createCon(
+                baseMutualOptions + "&sslMode=trust&enabledSslProtocolSuites=unknown", sslPort),
+        "Unsupported SSL protocol 'unknown'");
+  }
+
+  @Test
+  public void enabledSslCipherSuites() throws SQLException {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    try (Connection con =
+        createCon(
+            baseOptions
+                + "&sslMode=trust&enabledSslCipherSuites=TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+            sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+    Common.assertThrowsContains(
+        SQLException.class,
+        () ->
+            createCon(
+                baseMutualOptions + "&sslMode=trust&enabledSslCipherSuites=UNKNOWN_CIPHER",
+                sslPort),
+        "Unsupported SSL cipher");
+  }
+
+  @Test
+  public void mutualAuthSsl() throws SQLException {
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    Assumptions.assumeTrue(System.getenv("TEST_DB_CLIENT_PKCS") != null);
+
+    // without password
+    assertThrows(
+        SQLInvalidAuthorizationSpecException.class,
+        () ->
+            createCon(
+                baseMutualOptions
+                    + "&sslMode=trust&keyStore="
+                    + System.getenv("TEST_DB_CLIENT_PKCS"),
+                sslPort));
+    // with password
+    try (Connection con =
+        createCon(
+            baseMutualOptions
+                + "&sslMode=trust&keyStore="
+                + System.getenv("TEST_DB_CLIENT_PKCS")
+                + "&keyStorePassword=kspass",
+            sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    // with URL
+    boolean isWin = System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win");
+    try (Connection con =
+        createCon(
+            baseMutualOptions
+                + "&sslMode=trust&keyStore="
+                + "file://"
+                + (isWin ? "/" : "")
+                + System.getenv("TEST_DB_CLIENT_PKCS")
+                + "&keyStorePassword=kspass",
+            sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    // wrong keystore type
+    assertThrows(
+        SQLInvalidAuthorizationSpecException.class,
+        () ->
+            createCon(
+                baseMutualOptions
+                    + "&sslMode=trust&keyStoreType=JKS&keyStore="
+                    + System.getenv("TEST_DB_CLIENT_PKCS"),
+                sslPort));
+    // good keystore type
+    try (Connection con =
+        createCon(
+            baseMutualOptions
+                + "&sslMode=trust&keyStoreType=pkcs12&keyStore="
+                + System.getenv("TEST_DB_CLIENT_PKCS")
+                + "&keyStorePassword=kspass",
+            sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    // with system properties
+    System.setProperty("javax.net.ssl.keyStore", System.getenv("TEST_DB_CLIENT_PKCS"));
+    System.setProperty("javax.net.ssl.keyStorePassword", "kspass");
+    try (Connection con = createCon(baseMutualOptions + "&sslMode=trust", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    // wrong keystore type
+    System.setProperty("javax.net.ssl.keyStoreType", "JKS");
+    try (Connection con = createCon(baseMutualOptions + "&sslMode=trust", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+    try (Connection con = createCon(baseMutualOptions + "&sslMode=trust", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    System.clearProperty("javax.net.ssl.keyStoreType");
+    try (Connection con =
+        createCon(baseMutualOptions + "&sslMode=trust&keyStoreType=JKS", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    // without password
+    System.clearProperty("javax.net.ssl.keyStorePassword");
+    assertThrows(
+        SQLInvalidAuthorizationSpecException.class,
+        () -> createCon(baseMutualOptions + "&sslMode=trust", sslPort));
+  }
+
+  @Test
+  public void certificateMandatorySsl() throws Throwable {
+
+    String serverCertPath = retrieveCertificatePath();
+    Assumptions.assumeTrue(serverCertPath != null, "Canceled, server certificate not provided");
+
+    // certificate path, like  /path/certificate.crt
+    try (Connection con =
+        createCon(baseOptions + "&sslMode=VERIFY_CA&serverSslCert=" + serverCertPath, sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    try (Connection con =
+        createCon(baseOptions + "&sslMode=VERIFY_CA&serverSslCert=file:///wrongPath", sslPort)) {
+      assertNotNull(getSslVersion(con));
+    } catch (Exception e) {
+      assertTrue(e.getCause() instanceof FileNotFoundException);
+    }
+
+    if (!"localhost".equals(hostname)) {
+      try (Connection con =
+          createCon(
+              baseOptions + "&sslMode=VERIFY_FULL&serverSslCert=" + serverCertPath, sslPort)) {
+        assertNotNull(getSslVersion(con));
+      }
+
+      Configuration conf = Configuration.parse(mDefUrl);
+      HostAddress hostAddress = conf.addresses().get(0);
+      try {
+        proxy = new TcpProxy(hostAddress.host, sslPort == null ? hostAddress.port : sslPort);
+      } catch (IOException i) {
+        throw new SQLException("proxy error", i);
+      }
+
+      String url = mDefUrl.replaceAll("//([^/]*)/", "//localhost:" + proxy.getLocalPort() + "/");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () ->
+              DriverManager.getConnection(
+                  url + "&sslMode=VERIFY_FULL&serverSslCert=" + serverCertPath),
+          "DNS host \"localhost\" doesn't correspond to certificate");
+    }
+
+    String urlPath = Paths.get(serverCertPath).toUri().toURL().toString();
+    // file certificate path, like  file:/path/certificate.crt
+    try (Connection con =
+        createCon(baseOptions + "&sslMode=VERIFY_CA&serverSslCert=" + urlPath, sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    String certificateString = getServerCertificate(serverCertPath);
+    // file certificate, like  -----BEGIN CERTIFICATE-----...
+    try (Connection con =
+        createCon(baseOptions + "&sslMode=VERIFY_CA&serverSslCert=" + certificateString, sslPort)) {
+      assertNotNull(getSslVersion(con));
+    }
+
+    assertThrows(
+        SQLNonTransientConnectionException.class,
+        () -> createCon(baseOptions + "&sslMode=VERIFY_CA", sslPort));
+    assertThrows(
+        SQLInvalidAuthorizationSpecException.class,
+        () ->
+            createCon(
+                baseMutualOptions + "&sslMode=VERIFY_CA&serverSslCert=" + serverCertPath, sslPort));
+  }
+
+  private String getServerCertificate(String serverCertPath) throws SQLException {
+    try (BufferedReader br =
+        new BufferedReader(new InputStreamReader(new FileInputStream(serverCertPath)))) {
+      StringBuilder sb = new StringBuilder();
+      String line;
+      while ((line = br.readLine()) != null) {
+        sb.append(line);
+        sb.append("\n");
+      }
+      return sb.toString();
+    } catch (Exception e) {
+      throw new SQLException("abnormal exception", e);
+    }
+  }
+
+  public static String retrieveCertificatePath() throws Exception {
+    String serverCertificatePath = checkFileExists(System.getProperty("serverCertificatePath"));
+
+    // try local server
+    if (serverCertificatePath == null
+        && !"skysql".equals(System.getenv("srv"))
+        && !"skysql-ha".equals(System.getenv("srv"))) {
+
+      try (ResultSet rs = sharedConn.createStatement().executeQuery("select @@ssl_cert")) {
+        assertTrue(rs.next());
+        serverCertificatePath = checkFileExists(rs.getString(1));
+      }
+    }
+    if (serverCertificatePath == null) {
+      serverCertificatePath = checkFileExists("../../ssl/server.crt");
+    }
+    return serverCertificatePath;
+  }
+
+  private static String checkFileExists(String path) throws IOException {
+    if (path == null) return null;
+    File f = new File(path);
+    if (f.exists()) {
+      return f.getCanonicalPath().replace("\\", "/");
+    }
+    return null;
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/StatementTest.java b/src/test/java/org/mariadb/jdbc/integration/StatementTest.java
new file mode 100644
index 0000000..d8de05e
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/StatementTest.java
@@ -0,0 +1,966 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.Connection;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.plugin.Codec;
+
+public class StatementTest extends Common {
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS StatementTest");
+    stmt.execute("DROP TABLE IF EXISTS executeGenerated");
+    stmt.execute("DROP TABLE IF EXISTS executeGenerated2");
+    stmt.execute("DROP TABLE IF EXISTS testAffectedRow");
+    stmt.execute("DROP TABLE IF EXISTS bigIntId");
+    stmt.execute("DROP TABLE IF EXISTS testCONJ956");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE testCONJ956 (field varchar(300) NOT NULL)");
+    stmt.execute("CREATE TABLE StatementTest (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute(
+        "CREATE TABLE executeGenerated (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute(
+        "CREATE TABLE executeGenerated2 (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("CREATE TABLE testAffectedRow(id int)");
+    stmt.execute(
+        "CREATE TABLE bigIntId(`id` bigint(20) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, val"
+            + " VARCHAR(256))");
+    createSequenceTables();
+    stmt.execute("FLUSH TABLES");
+  }
+
+  @Test
+  public void ensureGetGeneratedKeysReturnsEmptyResult() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE IF NOT EXISTS key_test (id INT(11) NOT NULL)");
+    try (PreparedStatement ps =
+        sharedConn.prepareStatement(
+            "INSERT INTO key_test(id) VALUES(5)", Statement.RETURN_GENERATED_KEYS)) {
+      ps.execute();
+      ResultSet rs = ps.getGeneratedKeys();
+      assertFalse(rs.next());
+    }
+    try (PreparedStatement ps =
+        sharedConn.prepareStatement(
+            "UPDATE key_test set id=7 WHERE id=5", Statement.RETURN_GENERATED_KEYS)) {
+      ps.execute();
+      ResultSet rs = ps.getGeneratedKeys();
+      assertFalse(rs.next());
+    }
+
+    stmt.execute("DROP TABLE key_test");
+  }
+
+  @Test
+  public void longGeneratedId() throws SQLException {
+    longGeneratedId(BigInteger.ONE);
+    longGeneratedId(BigInteger.valueOf(Integer.MAX_VALUE));
+    longGeneratedId(BigInteger.valueOf(4294967295L));
+    longGeneratedId(BigInteger.valueOf(Long.MAX_VALUE));
+  }
+
+  public void longGeneratedId(BigInteger expected) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("ALTER TABLE bigIntId AUTO_INCREMENT=" + expected.toString());
+    stmt.execute(
+        "INSERT INTO bigIntId(val) value ('est')", java.sql.Statement.RETURN_GENERATED_KEYS);
+    ResultSet rs = stmt.getGeneratedKeys();
+
+    ResultSetMetaData rmeta = rs.getMetaData();
+    assertFalse(rmeta.isSigned(1));
+    assertTrue(rs.next());
+    if (expected.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) >= 1) {
+      assertThrowsContains(SQLDataException.class, () -> rs.getInt(1), "integer overflow");
+    } else {
+      assertEquals(expected.intValueExact(), rs.getInt(1));
+    }
+
+    if (expected.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) >= 1) {
+      assertThrowsContains(
+          SQLDataException.class, () -> rs.getLong(1), "cannot be decoded as Long");
+    } else {
+      assertEquals(expected.longValueExact(), rs.getLong(1));
+    }
+    assertTrue(expected.compareTo(((CompleteResult) rs).getBigInteger(1)) == 0);
+    assertTrue(new BigDecimal(expected).compareTo(rs.getBigDecimal(1)) == 0);
+  }
+
+  @Test
+  public void getConnection() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertEquals(ResultSet.TYPE_FORWARD_ONLY, stmt.getResultSetType());
+    assertEquals(ResultSet.CONCUR_READ_ONLY, stmt.getResultSetConcurrency());
+    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+    assertEquals(sharedConn, stmt.getConnection());
+
+    stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
+    assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, stmt.getResultSetType());
+    assertEquals(ResultSet.CONCUR_UPDATABLE, stmt.getResultSetConcurrency());
+    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+
+    stmt =
+        sharedConn.createStatement(
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE,
+            ResultSet.CLOSE_CURSORS_AT_COMMIT);
+    assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, stmt.getResultSetType());
+    assertEquals(ResultSet.CONCUR_UPDATABLE, stmt.getResultSetConcurrency());
+
+    // not supported
+    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+  }
+
+  @Test
+  public void setObjectError() throws SQLException {
+    try (PreparedStatement prep = sharedConn.prepareStatement("SELECT ?")) {
+      assertThrowsContains(
+          SQLException.class, () -> prep.setObject(1, "", Types.ARRAY), "Type not supported");
+      assertThrowsContains(
+          SQLException.class, () -> prep.setObject(1, "", JDBCType.ARRAY), "Type not supported");
+      assertThrowsContains(
+          SQLException.class,
+          () -> prep.setObject(1, "a", JDBCType.BLOB),
+          "Cannot convert a string to a Blob");
+      assertThrowsContains(
+          SQLException.class,
+          () -> prep.setObject(1, 'a', JDBCType.BLOB),
+          "Cannot convert a character to a Blob");
+    }
+  }
+
+  @Test
+  public void conj956() throws SQLException {
+    StringBuilder sb = new StringBuilder();
+    String sQuery = "SELECT EXISTS (SELECT 1 FROM testCONJ956 WHERE ((field=?)))";
+    for (int i = 1; i <= 300; i++) {
+      sb.append("a");
+      if (i < 204) {
+        continue;
+      }
+      PreparedStatement stmt = sharedConn.prepareStatement(sQuery);
+      stmt.setString(1, sb.toString());
+      stmt.executeQuery();
+    }
+  }
+
+  @Test
+  public void execute() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertTrue(stmt.execute("SELECT 1", Statement.RETURN_GENERATED_KEYS));
+    ResultSet rs = stmt.getGeneratedKeys();
+    Assertions.assertNull(rs.getWarnings());
+    assertFalse(rs.next());
+    assertNotNull(stmt.getResultSet());
+    assertEquals(-1, stmt.getUpdateCount());
+    assertFalse(stmt.getMoreResults());
+    assertEquals(-1, stmt.getUpdateCount());
+    if (!isXpand()) {
+      assertFalse(stmt.execute("DO 1"));
+      Assertions.assertNull(stmt.getResultSet());
+      assertEquals(0, stmt.getUpdateCount());
+      assertFalse(stmt.getMoreResults());
+      assertEquals(-1, stmt.getUpdateCount());
+    }
+
+    assertTrue(stmt.execute("SELECT 1", new int[] {1, 2}));
+    rs = stmt.getGeneratedKeys();
+    assertFalse(rs.next());
+
+    assertTrue(stmt.execute("SELECT 1", new String[] {"test", "test2"}));
+    rs = stmt.getGeneratedKeys();
+    assertFalse(rs.next());
+
+    stmt.close();
+  }
+
+  @Test
+  public void executeGenerated() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertFalse(stmt.execute("INSERT INTO executeGenerated(t2) values (100)"));
+
+    SQLException e = Assertions.assertThrows(SQLException.class, stmt::getGeneratedKeys);
+    assertTrue(e.getMessage().contains("Cannot return generated keys"));
+
+    assertFalse(
+        stmt.execute(
+            "INSERT INTO executeGenerated(t2) values (100)", Statement.RETURN_GENERATED_KEYS));
+    ResultSet rs = stmt.getGeneratedKeys();
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+  }
+
+  @Test
+  public void executeGeneratedBatch() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.addBatch("INSERT INTO executeGenerated2(t2) values (110)");
+    stmt.addBatch("INSERT INTO executeGenerated2(t2) values (120)");
+    int[] res = stmt.executeBatch();
+    assertArrayEquals(new int[] {1, 1}, res);
+    ResultSet rs = stmt.getGeneratedKeys();
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void executeUpdate() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("INSERT INTO StatementTest(t1, t2) values (1, 110), (2, 120)");
+    assertEquals(
+        2, stmt.executeUpdate("UPDATE StatementTest SET t2 = 130 WHERE t2 > 100 AND t2 < 200"));
+    assertEquals(2, stmt.getUpdateCount());
+    assertFalse(stmt.getMoreResults());
+    assertEquals(-1, stmt.getUpdateCount());
+
+    assertEquals(
+        2,
+        stmt.executeUpdate(
+            "UPDATE StatementTest SET t2 = 150 WHERE t2 > 100 AND t2 < 200", new int[] {1, 2}));
+    assertEquals(2, stmt.getUpdateCount());
+
+    assertEquals(
+        2,
+        stmt.executeUpdate(
+            "UPDATE StatementTest SET t2 = 150 WHERE t2 > 100 AND t2 < 200",
+            new String[] {"test", "test2"}));
+    assertEquals(2, stmt.getUpdateCount());
+
+    try {
+      stmt.executeUpdate("SELECT 1");
+      Assertions.fail();
+    } catch (SQLException sqle) {
+      assertTrue(
+          sqle.getMessage()
+              .contains("the given SQL statement produces an unexpected ResultSet object"));
+    }
+    if (!isXpand()) {
+      assertEquals(0, stmt.executeUpdate("DO 1"));
+    }
+  }
+
+  @Test
+  public void executeLargeUpdate() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("INSERT INTO StatementTest(t1, t2) values (10, 210), (12, 220)");
+    assertEquals(2, stmt.executeLargeUpdate("UPDATE StatementTest SET t2 = 230 WHERE t2 > 200"));
+    assertEquals(2L, stmt.getLargeUpdateCount());
+    assertFalse(stmt.getMoreResults());
+    assertEquals(-1L, stmt.getLargeUpdateCount());
+
+    assertEquals(
+        2,
+        stmt.executeLargeUpdate(
+            "UPDATE StatementTest SET t2 = 250 WHERE t2 > 200", new int[] {1, 2}));
+    assertEquals(2L, stmt.getLargeUpdateCount());
+
+    assertEquals(
+        2,
+        stmt.executeLargeUpdate(
+            "UPDATE StatementTest SET t2 = 250 WHERE t2 > 200", new String[] {"test", "test2"}));
+    assertEquals(2L, stmt.getLargeUpdateCount());
+
+    try {
+      stmt.executeLargeUpdate("SELECT 1");
+      Assertions.fail();
+    } catch (SQLException sqle) {
+      assertTrue(
+          sqle.getMessage()
+              .contains("the given SQL statement produces an unexpected ResultSet object"));
+    }
+    if (!isXpand()) {
+      assertEquals(0, stmt.executeLargeUpdate("DO 1"));
+    }
+  }
+
+  @Test
+  public void executeQuery() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT 1");
+    assertTrue(rs.next());
+    if (!isXpand()) {
+      rs = stmt.executeQuery("DO 1");
+      assertFalse(rs.next());
+    }
+  }
+
+  @Test
+  public void close() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertFalse(stmt.isClosed());
+    ResultSet rs = stmt.executeQuery("select * FROM sequence_1_to_10 LIMIT 1");
+    rs.next();
+    rs.getObject(1);
+
+    rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10000");
+    assertFalse(rs.isClosed());
+    stmt.close();
+    assertTrue(stmt.isClosed());
+    assertTrue(rs.isClosed());
+
+    Common.assertThrowsContains(
+        SQLException.class, stmt::clearBatch, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::isPoolable, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.setPoolable(true),
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        stmt::closeOnCompletion,
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        stmt::isCloseOnCompletion,
+        "Cannot do an operation on a closed statement");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        stmt::getResultSetConcurrency,
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::getFetchSize, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::getMoreResults, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.execute("ANY"),
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.executeUpdate("ANY"),
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.executeQuery("ANY"),
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::executeBatch, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::getConnection, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.getMoreResults(1),
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::cancel, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::getMaxRows, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::getLargeMaxRows, "Cannot do an operation on a closed statement");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.setMaxRows(1),
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.setEscapeProcessing(true),
+        "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::getQueryTimeout, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class, stmt::getUpdateCount, "Cannot do an operation on a closed statement");
+    Common.assertThrowsContains(
+        SQLException.class,
+        stmt::getLargeUpdateCount,
+        "Cannot do an operation on a closed statement");
+  }
+
+  @Test
+  public void maxRows() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertEquals(0, stmt.getMaxRows());
+    try {
+      stmt.setMaxRows(-1);
+      Assertions.fail();
+    } catch (SQLException e) {
+      assertTrue(e.getMessage().contains("max rows cannot be negative"));
+    }
+
+    stmt.setMaxRows(10);
+    assertEquals(10, stmt.getMaxRows());
+
+    ResultSet rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10000");
+    int i = 0;
+    while (rs.next()) {
+      i++;
+      assertEquals(i, rs.getInt(1));
+    }
+    assertEquals(10, i);
+
+    stmt.setQueryTimeout(2);
+    rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10000");
+    i = 0;
+    while (rs.next()) {
+      i++;
+      assertEquals(i, rs.getInt(1));
+    }
+    assertEquals(10, i);
+  }
+
+  @Test
+  public void largeMaxRows() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertEquals(0L, stmt.getLargeMaxRows());
+    try {
+      stmt.setLargeMaxRows(-1);
+      Assertions.fail();
+    } catch (SQLException e) {
+      assertTrue(e.getMessage().contains("max rows cannot be negative"));
+    }
+
+    stmt.setLargeMaxRows(10);
+    assertEquals(10L, stmt.getLargeMaxRows());
+
+    ResultSet rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10000");
+    int i = 0;
+    while (rs.next()) {
+      i++;
+      assertEquals(i, rs.getInt(1));
+    }
+    assertEquals(10, i);
+
+    stmt.setQueryTimeout(2);
+    rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10000");
+    i = 0;
+    while (rs.next()) {
+      i++;
+      assertEquals(i, rs.getInt(1));
+    }
+    assertEquals(10, i);
+  }
+
+  @Test
+  public void checkFixedData() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertFalse(stmt.isPoolable());
+    stmt.setPoolable(true);
+    assertFalse(stmt.isPoolable());
+    assertFalse(stmt.isWrapperFor(String.class));
+    assertFalse(stmt.isWrapperFor(null));
+    assertTrue(stmt.isWrapperFor(Statement.class));
+    stmt.unwrap(java.sql.Statement.class);
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.unwrap(String.class),
+        "he receiver is not a wrapper and does not implement the interface");
+    Common.assertThrowsContains(
+        SQLException.class, () -> stmt.setCursorName(""), "Cursors are not supported");
+
+    assertEquals(ResultSet.FETCH_FORWARD, stmt.getFetchDirection());
+    stmt.setFetchDirection(ResultSet.FETCH_REVERSE);
+    assertEquals(ResultSet.FETCH_FORWARD, stmt.getFetchDirection());
+    assertEquals(ResultSet.CONCUR_READ_ONLY, stmt.getResultSetConcurrency());
+    assertEquals(ResultSet.TYPE_FORWARD_ONLY, stmt.getResultSetType());
+    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, stmt.getResultSetHoldability());
+    assertEquals(0, stmt.getMaxFieldSize());
+    stmt.setMaxFieldSize(100);
+    assertEquals(0, stmt.getMaxFieldSize());
+  }
+
+  @Test
+  public void getMoreResults() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10000");
+    assertFalse(stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT));
+    assertFalse(rs.isClosed());
+
+    rs = stmt.executeQuery("SELECT * FROM sequence_1_to_10000");
+    stmt.getMoreResults(Statement.CLOSE_CURRENT_RESULT);
+    assertTrue(rs.isClosed());
+    stmt.close();
+  }
+
+  @Test
+  @Timeout(20)
+  public void queryTimeout() {
+    Assumptions.assumeTrue(
+        isMariaDBServer()
+            && !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !isXpand());
+    Statement stmt = sharedConn.createStatement();
+
+    Common.assertThrowsContains(
+        SQLException.class, () -> stmt.setQueryTimeout(-1), "Query timeout cannot be negative");
+
+    Common.assertThrowsContains(
+        SQLTimeoutException.class,
+        () -> {
+          stmt.setQueryTimeout(1);
+          assertEquals(1, stmt.getQueryTimeout());
+          stmt.execute(
+              "select * from information_schema.columns as c1,  information_schema.tables,"
+                  + " information_schema.tables as t2");
+        },
+        "Query execution was interrupted (max_statement_time exceeded)");
+  }
+
+  @Test
+  public void smallQueryTimeout() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setQueryTimeout(1);
+    stmt.execute("SELECT 1");
+
+    stmt.setMaxRows(1);
+    stmt.execute("SELECT 1");
+
+    stmt.setQueryTimeout(0);
+    stmt.execute("SELECT 1");
+  }
+
+  @Test
+  public void escaping() throws Exception {
+    try (Connection con =
+        (Connection) DriverManager.getConnection(mDefUrl + "&dumpQueriesOnException=true")) {
+      Statement stmt = con.createStatement();
+      Common.assertThrowsContains(
+          SQLException.class,
+          () ->
+              stmt.executeQuery(
+                  "select {fn timestampdiff(SQL_TSI_HOUR, '2003-02-01','2003-05-01')} df df "),
+          "select {fn timestampdiff" + "(SQL_TSI_HOUR, '2003-02-01','2003-05-01')} df df ");
+      stmt.setEscapeProcessing(true);
+      Common.assertThrowsContains(
+          SQLException.class,
+          () ->
+              stmt.executeQuery(
+                  "select {fn timestampdiff(SQL_TSI_HOUR, '2003-02-01','2003-05-01')} df df "),
+          "select timestampdiff(HOUR, '2003-02-01','2003-05-01') df df ");
+    }
+  }
+
+  @Test
+  public void testWarnings() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
+    Assumptions.assumeTrue(isMariaDBServer() && !isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+
+    // connection level
+    Assertions.assertNull(sharedConn.getWarnings());
+    stmt.executeQuery("select now() = 1");
+    SQLWarning warning = sharedConn.getWarnings();
+    assertTrue(warning.getMessage().contains("ncorrect datetime value: '1'"));
+    stmt.executeQuery("select now() = 1");
+    sharedConn.clearWarnings();
+    Assertions.assertNull(sharedConn.getWarnings());
+
+    // statement level
+    ResultSet rs = stmt.executeQuery("select now() = 1");
+    warning = rs.getWarnings();
+    assertTrue(warning.getMessage().contains("ncorrect datetime value: '1'"));
+
+    rs = stmt.executeQuery("select now() = 1");
+    rs.clearWarnings();
+    Assertions.assertNull(rs.getWarnings());
+
+    stmt.executeQuery("select now() = 1");
+    warning = stmt.getWarnings();
+    assertTrue(warning.getMessage().contains("ncorrect datetime value: '1'"));
+
+    stmt.executeQuery("select now() = 1");
+    stmt.clearWarnings();
+    Assertions.assertNull(stmt.getWarnings());
+  }
+
+  @Test
+  public void cancel() throws Exception {
+    Assumptions.assumeTrue(
+        isMariaDBServer()
+            && !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.cancel(); // will do nothing
+
+    ExecutorService exec = Executors.newFixedThreadPool(1);
+
+    Common.assertThrowsContains(
+        SQLTimeoutException.class,
+        () -> {
+          exec.execute(new CancelThread(stmt));
+          stmt.execute(
+              "select * from information_schema.columns as c1,  information_schema.tables,"
+                  + " information_schema.tables as t2");
+          exec.shutdown();
+        },
+        "Query execution was interrupted");
+  }
+
+  @Test
+  public void fetch() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    Statement stmt2 = sharedConn.createStatement();
+    Common.assertThrowsContains(
+        SQLException.class, () -> stmt.setFetchSize(-10), "invalid fetch size");
+
+    stmt.setFetchSize(10);
+    assertEquals(10, stmt.getFetchSize());
+    ResultSet rs = stmt.executeQuery("select * FROM sequence_1_to_10000");
+
+    for (int i = 1; i <= 10000; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+
+    assertFalse(rs.next());
+
+    rs = stmt.executeQuery("select * FROM sequence_1_to_10");
+    ResultSet rs2 = stmt2.executeQuery("SELECT 200");
+    for (int i = 1; i <= 10; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertTrue(rs2.next());
+    assertEquals(200, rs2.getInt(1));
+  }
+
+  @Test
+  public void fetchUnFinishedSameStatement() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(10);
+    assertEquals(10, stmt.getFetchSize());
+    ResultSet rs = stmt.executeQuery("select * FROM sequence_1_to_10000");
+
+    for (int i = 1; i <= 5000; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+
+    ResultSet rs2 = stmt.executeQuery("select * FROM sequence_1_to_10000");
+
+    for (int i = 5001; i <= 10000; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+
+    for (int i = 1; i <= 10000; i++) {
+      assertTrue(rs2.next());
+      assertEquals(i, rs2.getInt(1));
+    }
+    assertFalse(rs2.next());
+  }
+
+  @Test
+  public void fetchUnFinishedOtherStatement() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(5);
+    assertEquals(5, stmt.getFetchSize());
+    ResultSet rs = stmt.executeQuery("select * FROM sequence_1_to_10000");
+
+    for (int i = 1; i <= 10; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+
+    Statement stmt2 = sharedConn.createStatement();
+    ResultSet rs2 = stmt2.executeQuery("select * FROM sequence_1_to_10000");
+
+    for (int i = 11; i <= 10000; i++) {
+      assertTrue(rs.next(), "val " + i);
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+
+    for (int i = 1; i <= 10000; i++) {
+      assertTrue(rs2.next());
+      assertEquals(i, rs2.getInt(1));
+    }
+    assertFalse(rs2.next());
+  }
+
+  @Test
+  public void fetchUnfinished() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(1);
+    stmt.executeQuery("select * FROM sequence_1_to_10");
+    assertFalse(stmt.getMoreResults());
+
+    Statement stmt2 = sharedConn.createStatement();
+    ResultSet rs = stmt2.executeQuery("SELECT 1");
+    rs.next();
+    assertEquals(1, rs.getInt(1));
+  }
+
+  @Test
+  public void fetchClose() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(10);
+    assertEquals(10, stmt.getFetchSize());
+    ResultSet rs = stmt.executeQuery("select * FROM sequence_1_to_10000");
+
+    for (int i = 1; i <= 5000; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    stmt.close();
+    assertTrue(rs.isClosed());
+    stmt.close();
+
+    Statement stmt2 = sharedConn.createStatement();
+    ResultSet rs2 = stmt2.executeQuery("select * FROM sequence_1_to_10000");
+    for (int i = 1; i <= 10000; i++) {
+      assertTrue(rs2.next());
+      assertEquals(i, rs2.getInt(1));
+    }
+    assertFalse(rs2.next());
+  }
+
+  @Test
+  public void executeBatchBasic() throws SQLException {
+    executeBatchBasic(sharedConn);
+    try (Connection con = createCon("allowLocalInfile=true")) {
+      executeBatchBasic(con);
+    }
+  }
+
+  private void executeBatchBasic(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    assertArrayEquals(new int[0], stmt.executeBatch());
+    stmt.clearBatch();
+    stmt.execute("DROP TABLE IF EXISTS executeBatchBasic");
+    stmt.execute(
+        "CREATE TABLE executeBatchBasic (t1 int not null primary key auto_increment, t2 int)");
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> stmt.addBatch(null),
+        "null cannot be set to addBatch(String sql)");
+
+    stmt.addBatch("INSERT INTO executeBatchBasic(t2) VALUES (55)");
+    stmt.setEscapeProcessing(true);
+    stmt.addBatch("INSERT INTO executeBatchBasic(t2) VALUES (56)");
+    int[] ret = stmt.executeBatch();
+    Assertions.assertArrayEquals(new int[] {1, 1}, ret);
+
+    ret = stmt.executeBatch();
+    Assertions.assertArrayEquals(new int[0], ret);
+
+    stmt.addBatch("INSERT INTO executeLargeBatchBasic(t2) VALUES (57)");
+    stmt.clearBatch();
+    ret = stmt.executeBatch();
+    Assertions.assertArrayEquals(new int[0], ret);
+    assertArrayEquals(new int[0], stmt.executeBatch());
+    stmt.addBatch("INSERT INTO executeLargeBatchBasic(t2) VALUES (57)");
+    stmt.addBatch("WRONG QUERY");
+    try {
+      stmt.executeBatch();
+      fail();
+    } catch (BatchUpdateException e) {
+      assertTrue(
+          e.getMessage().contains("You have an error in your SQL syntax")
+              || e.getMessage().contains("syntax error"));
+      assertNotNull(e.getCause());
+      assertEquals(e.getCause().getMessage(), e.getMessage());
+      assertEquals(((SQLException) e.getCause()).getSQLState(), e.getSQLState());
+      assertEquals(((SQLException) e.getCause()).getErrorCode(), e.getErrorCode());
+    }
+  }
+
+  @Test
+  public void executeLargeBatchBasic() throws SQLException {
+    executeLargeBatchBasic(sharedConn);
+    try (Connection con = createCon("allowLocalInfile=true")) {
+      executeLargeBatchBasic(con);
+    }
+  }
+
+  private void executeLargeBatchBasic(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    assertArrayEquals(new long[0], stmt.executeLargeBatch());
+    stmt.clearBatch();
+    stmt.execute("DROP TABLE IF EXISTS executeLargeBatchBasic");
+    stmt.execute(
+        "CREATE TABLE executeLargeBatchBasic (t1 int not null primary key auto_increment, t2 int)");
+    stmt.addBatch("INSERT INTO executeLargeBatchBasic(t2) VALUES (55)");
+    stmt.addBatch("INSERT INTO executeLargeBatchBasic(t2) VALUES (56)");
+    long[] ret = stmt.executeLargeBatch();
+    Assertions.assertArrayEquals(new long[] {1, 1}, ret);
+
+    ret = stmt.executeLargeBatch();
+    Assertions.assertArrayEquals(new long[0], ret);
+
+    stmt.addBatch("INSERT INTO executeLargeBatchBasic(t2) VALUES (57)");
+    stmt.clearBatch();
+    ret = stmt.executeLargeBatch();
+    Assertions.assertArrayEquals(new long[0], ret);
+    ret = stmt.executeLargeBatch();
+    Assertions.assertArrayEquals(new long[0], ret);
+    stmt.addBatch("INSERT INTO executeLargeBatchBasic(t2) VALUES (57)");
+    stmt.addBatch("WRONG QUERY");
+    try {
+      stmt.executeBatch();
+      fail();
+    } catch (BatchUpdateException e) {
+      assertTrue(
+          e.getMessage().contains("You have an error in your SQL syntax")
+              || e.getMessage().contains("syntax error"));
+      assertNotNull(e.getCause());
+      assertEquals(e.getCause().getMessage(), e.getMessage());
+      assertEquals(((SQLException) e.getCause()).getSQLState(), e.getSQLState());
+      assertEquals(((SQLException) e.getCause()).getErrorCode(), e.getErrorCode());
+    }
+  }
+
+  @Test
+  public void fetchSize() throws SQLException {
+    assertEquals(0, sharedConn.createStatement().getFetchSize());
+    try (Connection con = createCon("&defaultFetchSize=10")) {
+      assertEquals(10, con.createStatement().getFetchSize());
+      try (PreparedStatement prep = con.prepareStatement("SELECT ?")) {
+        assertEquals(10, prep.getFetchSize());
+      }
+    }
+  }
+
+  @Test
+  public void moreResults() throws SQLException {
+    // error MXS-3929 for maxscale 6.2.0
+    Assumptions.assumeTrue(
+        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.2.0"));
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP PROCEDURE IF EXISTS multi");
+    stmt.setFetchSize(3);
+    stmt.execute(
+        "CREATE PROCEDURE multi() BEGIN SELECT * from sequence_1_to_10; SELECT * FROM"
+            + " sequence_1_to_10000;SELECT 2; END");
+    stmt.execute("CALL multi()");
+    assertTrue(stmt.getMoreResults());
+    ResultSet rs = stmt.getResultSet();
+    int i = 1;
+    while (rs.next()) {
+      assertEquals(i++, rs.getInt(1));
+    }
+    assertEquals(10001, i);
+    stmt.setFetchSize(3);
+
+    rs = stmt.executeQuery("CALL multi()");
+    assertFalse(rs.isClosed());
+    stmt.setFetchSize(0); // force more result to load all remaining result-set
+    assertTrue(stmt.getMoreResults());
+    assertTrue(rs.isClosed());
+    rs = stmt.getResultSet();
+    i = 1;
+    while (rs.next()) {
+      assertEquals(i++, rs.getInt(1));
+    }
+
+    stmt.setFetchSize(3);
+    rs = stmt.executeQuery("CALL multi()");
+    assertFalse(rs.isClosed());
+    stmt.setFetchSize(0); // force more result to load all remaining result-set
+    assertTrue(stmt.getMoreResults(java.sql.Statement.KEEP_CURRENT_RESULT));
+    assertFalse(rs.isClosed());
+    i = 1;
+    while (rs.next()) {
+      assertEquals(i++, rs.getInt(1));
+    }
+    assertEquals(11, i);
+    rs = stmt.getResultSet();
+    i = 1;
+    while (rs.next()) {
+      assertEquals(i++, rs.getInt(1));
+    }
+    assertEquals(10001, i);
+
+    rs = stmt.executeQuery("CALL multi()");
+    stmt.close();
+    assertTrue(rs.isClosed());
+  }
+
+  @Test
+  public void closeOnCompletion() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    assertFalse(stmt.isCloseOnCompletion());
+    stmt.closeOnCompletion();
+    assertTrue(stmt.isCloseOnCompletion());
+    assertFalse(stmt.isClosed());
+    ResultSet rs = stmt.executeQuery("SELECT 1");
+    assertFalse(rs.isClosed());
+    assertFalse(stmt.isClosed());
+    rs.close();
+    assertTrue(rs.isClosed());
+    assertTrue(stmt.isClosed());
+  }
+
+  private static class CancelThread implements Runnable {
+
+    private final java.sql.Statement stmt;
+
+    public CancelThread(java.sql.Statement stmt) {
+      this.stmt = stmt;
+    }
+
+    @Override
+    public void run() {
+      try {
+        Thread.sleep(100);
+        stmt.cancel();
+      } catch (SQLException | InterruptedException e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @Test
+  public void testAffectedRow() throws SQLException {
+    testAffectedRow(false);
+    if (!isXpand()) {
+      testAffectedRow(true);
+    }
+  }
+
+  @Test
+  public void ensureClassDefined() {
+    for (Codec<?> codec : sharedConn.getContext().getConf().codecs()) {
+      Type it = codec.getClass().getGenericInterfaces()[0];
+      ParameterizedType parameterizedType = (ParameterizedType) it;
+      Type typeParameter = parameterizedType.getActualTypeArguments()[0];
+      if (!"byte[]".equals(codec.className()))
+        assertEquals(((Class<?>) typeParameter).getName(), codec.className());
+    }
+  }
+
+  private void testAffectedRow(boolean useAffectedRows) throws SQLException {
+    try (Connection con = createCon("&useAffectedRows=" + useAffectedRows)) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("TRUNCATE testAffectedRow");
+      stmt.execute("START TRANSACTION");
+      stmt.execute("INSERT INTO testAffectedRow values (1), (1), (2), (3)");
+      int rowCount = stmt.executeUpdate("UPDATE testAffectedRow set id = 1");
+      assertEquals(useAffectedRows ? 2 : 4, rowCount);
+      con.rollback();
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/UnixsocketTest.java b/src/test/java/org/mariadb/jdbc/integration/UnixsocketTest.java
new file mode 100644
index 0000000..d214540
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/UnixsocketTest.java
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.sql.SQLNonTransientConnectionException;
+import java.util.Properties;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+
+public class UnixsocketTest extends Common {
+  @Test
+  public void testConnectWithUnixSocketWhenDBNotUp() throws IOException {
+    Assumptions.assumeTrue(!isWindows());
+    Assumptions.assumeTrue(
+        !"maxscale".equals(System.getenv("srv"))
+            && !"skysql".equals(System.getenv("srv"))
+            && !"xpand".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv")));
+
+    String url = mDefUrl + "&localSocket=/tmp/not_valid_socket&localSocketAddress=localhost";
+
+    java.sql.Driver driver = new org.mariadb.jdbc.Driver();
+
+    Runtime rt = Runtime.getRuntime();
+    // System.out.println("netstat-apnx | grep " + ProcessHandle.current().pid());
+    String[] commands = {"/bin/sh", "-c", "netstat -apnx | grep " + ProcessHandle.current().pid()};
+    Process proc = rt.exec(commands);
+
+    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+    int initialLines = 0;
+    while (stdInput.readLine() != null) {
+      initialLines++;
+    }
+    proc.destroy();
+
+    for (int i = 0; i < 10; i++) {
+      assertThrows(
+          SQLNonTransientConnectionException.class,
+          () -> {
+            driver.connect(url, new Properties());
+          });
+    }
+    proc = rt.exec(commands);
+    stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+    int finalLines = 0;
+    while (stdInput.readLine() != null) {
+      finalLines++;
+    }
+    proc.destroy();
+    assertEquals(
+        finalLines,
+        initialLines,
+        "Error Leaking socket file descriptors. initial :"
+            + initialLines
+            + " but ending with "
+            + finalLines);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/UpdateResultSetTest.java b/src/test/java/org/mariadb/jdbc/integration/UpdateResultSetTest.java
new file mode 100644
index 0000000..18ba2e2
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/UpdateResultSetTest.java
@@ -0,0 +1,1174 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import org.junit.jupiter.api.*;
+
+public class UpdateResultSetTest extends Common {
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    org.mariadb.jdbc.Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS testnoprimarykey");
+    stmt.execute("DROP TABLE IF EXISTS testMultipleTable1");
+    stmt.execute("DROP TABLE IF EXISTS testMultipleTable2");
+    stmt.execute("DROP TABLE IF EXISTS testOneNoTable");
+    stmt.execute("DROP TABLE IF EXISTS UpdateWithoutPrimary");
+    stmt.execute("DROP TABLE IF EXISTS testbasicprimarykey");
+    stmt.execute("DROP DATABASE IF EXISTS testConnectorJ");
+    stmt.execute("DROP TABLE IF EXISTS testUpdateWhenFetch");
+    stmt.execute("DROP TABLE IF EXISTS testExpError");
+    stmt.execute("DROP TABLE IF EXISTS `testDefaultUUID`");
+    stmt.execute("DROP TABLE IF EXISTS `test_update_max`");
+    stmt.execute("DROP TABLE IF EXISTS `testAutoIncrement`");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    org.mariadb.jdbc.Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE testnoprimarykey(`id` INT NOT NULL,`t1` VARCHAR(50) NOT NULL)");
+    stmt.execute(
+        "CREATE TABLE testbasicprimarykey(`id` INT NOT NULL,`t1` VARCHAR(50) NOT NULL, CONSTRAINT"
+            + " pk PRIMARY KEY (id))");
+    stmt.execute(
+        "CREATE TABLE testMultipleTable1(`id1` INT NOT NULL AUTO_INCREMENT,`t1` VARCHAR(50)"
+            + " NULL,PRIMARY KEY (`id1`))");
+    stmt.execute(
+        "CREATE TABLE testMultipleTable2(`id2` INT NOT NULL AUTO_INCREMENT,`t1` VARCHAR(50)"
+            + " NULL,PRIMARY KEY (`id2`))");
+    stmt.execute(
+        "CREATE TABLE testOneNoTable(`id1` INT NOT NULL AUTO_INCREMENT,`t1` VARCHAR(50)"
+            + " NULL,PRIMARY KEY (`id1`))");
+    stmt.execute(
+        "CREATE TABLE testAutoIncrement(`id1` INT NOT NULL AUTO_INCREMENT,`t1` VARCHAR(50)"
+            + " NULL,PRIMARY KEY (`id1`))");
+
+    stmt.execute(
+        "CREATE TABLE testUpdateWhenFetch("
+            + "`id` INT NOT NULL AUTO_INCREMENT,"
+            + "`t1` VARCHAR(50) NOT NULL,"
+            + "`t2` VARCHAR(50) NULL default 'default-value',"
+            + "PRIMARY KEY (`id`))"
+            + "DEFAULT CHARSET=utf8");
+    stmt.execute(
+        "CREATE TABLE testExpError ("
+            + " `id1` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,"
+            + "`t1` varchar(100) DEFAULT NULL,"
+            + "`t2` varchar(100) DEFAULT NULL)");
+    if (isMariaDBServer() && minVersion(10, 2, 0)) {
+      stmt.execute(
+          "CREATE TABLE `testDefaultUUID` ("
+              + "`column1` varchar(40) NOT NULL DEFAULT uuid(),"
+              + "`column2` varchar(100) DEFAULT NULL,"
+              + " PRIMARY KEY (`column1`))");
+    }
+    stmt.execute(
+        "CREATE TABLE test_update_max(`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,`t1` VARCHAR(50)"
+            + " NOT NULL)");
+  }
+
+  /**
+   * Test error message when no primary key.
+   *
+   * @throws Exception not expected
+   */
+  @Test
+  public void testNoPrimaryKey() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("INSERT INTO testnoprimarykey VALUES (1, 't1'), (2, 't2')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT * FROM testnoprimarykey",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.updateString(1, "1"),
+          "ResultSet cannot be updated. Cannot update rows, since no primary field is present in"
+              + " query");
+    }
+  }
+
+  @Test
+  public void testBasicPrimaryKey() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("INSERT INTO testbasicprimarykey VALUES (1, 't1'), (2, 't2')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT t1 FROM testbasicprimarykey",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.updateString(1, "val"),
+          "ResultSet cannot be updated. Cannot update rows, since primary field id is not present"
+              + " in query");
+    }
+  }
+
+  @Test
+  public void testNoDatabase() throws Exception {
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> rs.updateString(1, "1"),
+          "The result-set contains fields without without any database/table information");
+    }
+  }
+
+  @Test
+  public void testMultipleTable() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    stmt.executeQuery("INSERT INTO testMultipleTable1(t1) values ('1')");
+    stmt.executeQuery("INSERT INTO testMultipleTable2(t1) values ('2')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT * FROM testMultipleTable1, testMultipleTable2",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> rs.updateString("t1", "new value"),
+          "ResultSet cannot be updated. The result-set contains fields on different tables");
+    } finally {
+      sharedConn.rollback();
+    }
+  }
+
+  @Test
+  public void testOneNoTable() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.executeQuery("INSERT INTO testOneNoTable(t1) values ('1')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT *, now() FROM testOneNoTable",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> rs.updateString("t1", "new value"),
+          "ResultSet cannot be updated. "
+              + "The result-set contains fields without without any database/table information");
+    }
+  }
+
+  @Test
+  public void testAutoIncrement() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    PreparedStatement pstmt =
+        sharedConn.prepareStatement("INSERT INTO testAutoIncrement(t1) values (?)");
+    pstmt.setString(1, "1");
+    pstmt.execute();
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT id1, t1 FROM testAutoIncrement",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+
+      rs.moveToInsertRow();
+      rs.updateString(2, "0-1");
+      rs.insertRow();
+    }
+
+    ResultSet rs = stmt.executeQuery("SELECT * FROM testAutoIncrement");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1", rs.getString(2));
+    rs.next();
+    assertEquals(2, rs.getInt(1));
+    assertEquals("0-1", rs.getString(2));
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void testMultipleDatabase() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    try {
+      stmt.execute("DROP DATABASE testConnectorJ");
+    } catch (SQLException sqle) {
+      // eat
+    }
+    stmt.execute("CREATE DATABASE testConnectorJ");
+    stmt.execute("DROP TABLE IF EXISTS testMultipleDatabase");
+    stmt.execute(
+        "CREATE TABLE testMultipleDatabase(`id1` INT NOT NULL AUTO_INCREMENT,`t1` VARCHAR(50)"
+            + " NULL,PRIMARY KEY (`id1`))");
+    stmt.execute(
+        "CREATE TABLE testConnectorJ.testMultipleDatabase(`id2` INT NOT NULL AUTO_INCREMENT,`t2`"
+            + " VARCHAR(50) NULL,PRIMARY KEY (`id2`))");
+    stmt.executeQuery("INSERT INTO testMultipleDatabase(t1) values ('1')");
+    stmt.executeQuery("INSERT INTO testConnectorJ.testMultipleDatabase(t2) values ('2')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT * FROM "
+                + sharedConn.getCatalog()
+                + ".testMultipleDatabase, testConnectorJ.testMultipleDatabase",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      Common.assertThrowsContains(
+          SQLFeatureNotSupportedException.class,
+          () -> rs.updateString("t1", "new value"),
+          "The result-set contains more than one database");
+    }
+  }
+
+  @Test
+  public void testMeta() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE UpdateWithoutPrimary(`id` INT NOT NULL AUTO_INCREMENT,"
+            + "`t1` VARCHAR(50) NOT NULL,"
+            + "`t2` VARCHAR(50) NULL default 'default-value',"
+            + "PRIMARY KEY (`id`))");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    stmt.executeQuery("INSERT INTO UpdateWithoutPrimary(t1,t2) values ('1-1','1-2')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT t1, t2 FROM UpdateWithoutPrimary",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> {
+            rs.updateString(1, "1-1-bis");
+            rs.updateRow();
+          },
+          "ResultSet cannot be updated. Cannot update rows, since primary field id is not present"
+              + " in query");
+      Common.assertThrowsContains(
+          SQLException.class,
+          rs::deleteRow,
+          "ResultSet cannot be updated. Cannot update rows, since primary field id is not present"
+              + " in query");
+      ResultSetMetaData rsmd = rs.getMetaData();
+      assertFalse(rsmd.isReadOnly(1));
+      assertFalse(rsmd.isReadOnly(2));
+      assertTrue(rsmd.isWritable(1));
+      assertTrue(rsmd.isWritable(2));
+      assertTrue(rsmd.isDefinitelyWritable(1));
+      assertTrue(rsmd.isDefinitelyWritable(2));
+
+      Common.assertThrowsContains(
+          SQLException.class, () -> rsmd.isReadOnly(3), "wrong column index 3");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rsmd.isWritable(3), "wrong column index 3");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rsmd.isDefinitelyWritable(3), "wrong column index 3");
+    }
+    ResultSet rs = stmt.executeQuery("SELECT id, t1, t2 FROM UpdateWithoutPrimary");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1-1", rs.getString(2));
+    assertEquals("1-2", rs.getString(3));
+    assertFalse(rs.next());
+    sharedConn.rollback();
+  }
+
+  @Test
+  public void testUpdateWhenFetch() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    PreparedStatement pstmt =
+        sharedConn.prepareStatement("INSERT INTO testUpdateWhenFetch(t1,t2) values (?, ?)");
+    for (int i = 1; i < 100; i++) {
+      pstmt.setString(1, i + "-1");
+      pstmt.setString(2, i + "-2");
+      pstmt.addBatch();
+    }
+    pstmt.executeBatch();
+
+    String utf8escapeQuote = "你好 '' \" \\";
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT id, t1, t2 FROM testUpdateWhenFetch",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      preparedStatement.setFetchSize(2);
+      ResultSet rs = preparedStatement.executeQuery();
+      assertFalse(rs.rowInserted());
+      assertFalse(rs.rowUpdated());
+
+      rs.moveToInsertRow();
+      rs.updateInt(1, -1);
+      rs.updateString(2, "0-1");
+      rs.updateString(3, "0-2");
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class, () -> rs.updateObject(10, "val"), "No such column: 10");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.updateObject(2, new SQLException("dd")),
+          "not supported type");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.updateObject(2, new SQLException("dd"), null, 20),
+          "not supported type");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.updateObject("t2", new SQLException("dd"), null),
+          "not supported type");
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.updateObject("t2", new SQLException("dd"), null, 20),
+          "not supported type");
+
+      Common.assertThrowsContains(
+          SQLSyntaxErrorException.class, () -> rs.updateObject(-10, "val"), "No such column: -10");
+      rs.insertRow();
+      assertTrue(rs.rowInserted());
+
+      rs.next();
+      assertFalse(rs.rowInserted());
+      rs.next();
+      rs.updateString(2, utf8escapeQuote);
+      assertFalse(rs.rowUpdated());
+      assertFalse(rs.rowDeleted());
+      assertFalse(rs.rowInserted());
+      rs.updateRow();
+      assertTrue(rs.rowUpdated());
+    }
+
+    ResultSet rs = stmt.executeQuery("SELECT id, t1, t2 FROM testUpdateWhenFetch");
+    assertTrue(rs.next());
+    assertEquals(-1, rs.getInt(1));
+    assertEquals("0-1", rs.getString(2));
+    assertEquals("0-2", rs.getString(3));
+
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1-1", rs.getString(2));
+    assertEquals("1-2", rs.getString(3));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertEquals(utf8escapeQuote, rs.getString(2));
+    assertEquals("2-2", rs.getString(3));
+
+    for (int i = 3; i < 100; i++) {
+      assertTrue(rs.next());
+      assertEquals(i + "-1", rs.getString(2));
+      assertEquals(i + "-2", rs.getString(3));
+    }
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void testPrimaryGenerated() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS PrimaryGenerated");
+    stmt.execute(
+        "CREATE TABLE PrimaryGenerated("
+            + "`id` INT NOT NULL AUTO_INCREMENT,"
+            + "`t1` VARCHAR(50) NOT NULL,"
+            + "`t2` VARCHAR(50) NULL default 'default-value',"
+            + "PRIMARY KEY (`id`))");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT t1, t2, id FROM PrimaryGenerated",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertFalse(rs.next());
+
+      rs.moveToInsertRow();
+      rs.updateString(1, "1-1");
+      rs.updateString(2, "1-2");
+      rs.insertRow();
+
+      rs.moveToInsertRow();
+      rs.updateString(1, "2-1");
+      rs.insertRow();
+
+      rs.moveToInsertRow();
+      rs.updateString(2, "3-2");
+      assertThrows(SQLException.class, rs::insertRow);
+
+      rs.absolute(1);
+      assertEquals("1-1", rs.getString(1));
+      assertEquals("1-2", rs.getString(2));
+      assertEquals(1, rs.getInt(3));
+
+      assertTrue(rs.next());
+      assertEquals("2-1", rs.getString(1));
+      assertEquals("default-value", rs.getString(2));
+      assertEquals(2, rs.getInt(3));
+
+      assertFalse(rs.next());
+    }
+
+    ResultSet rs = stmt.executeQuery("SELECT id, t1, t2 FROM PrimaryGenerated");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("1-1", rs.getString(2));
+    assertEquals("1-2", rs.getString(3));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertEquals("2-1", rs.getString(2));
+    assertEquals("default-value", rs.getString(3));
+
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void testPrimaryGeneratedDefault() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS testPrimaryGeneratedDefault");
+    stmt.execute(
+        "CREATE TABLE testPrimaryGeneratedDefault("
+            + "`id` INT NOT NULL AUTO_INCREMENT,"
+            + "`t1` VARCHAR(50) NOT NULL default 'default-value1',"
+            + "`t2` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+            + "PRIMARY KEY (`id`))");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT id, t1, t2 FROM testPrimaryGeneratedDefault",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertFalse(rs.next());
+      rs.moveToInsertRow();
+      rs.insertRow();
+
+      rs.moveToInsertRow();
+      rs.insertRow();
+
+      rs.first();
+      rs.moveToInsertRow();
+      rs.first();
+
+      rs.last();
+      rs.moveToInsertRow();
+      rs.last();
+
+      rs.afterLast();
+      rs.moveToInsertRow();
+      rs.afterLast();
+
+      rs.relative(-1);
+      rs.moveToInsertRow();
+      rs.relative(-1);
+
+      rs.next();
+      rs.moveToInsertRow();
+      rs.next();
+
+      rs.previous();
+      rs.moveToInsertRow();
+      rs.previous();
+
+      rs.beforeFirst();
+      rs.moveToInsertRow();
+      rs.beforeFirst();
+
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt(1));
+      assertEquals("default-value1", rs.getString(2));
+      assertNotNull(rs.getDate(3));
+
+      assertTrue(rs.next());
+      assertEquals(2, rs.getInt(1));
+      assertEquals("default-value1", rs.getString(2));
+      assertNotNull(rs.getDate(3));
+      assertFalse(rs.next());
+    }
+
+    ResultSet rs = stmt.executeQuery("SELECT id, t1, t2 FROM testPrimaryGeneratedDefault");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("default-value1", rs.getString(2));
+    assertNotNull(rs.getDate(3));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+    assertEquals("default-value1", rs.getString(2));
+    assertNotNull(rs.getDate(3));
+
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void testDelete() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS testDelete");
+    stmt.execute(
+        "CREATE TABLE testDelete("
+            + "`id` INT NOT NULL,"
+            + "`id2` INT NOT NULL,"
+            + "`t1` VARCHAR(50),"
+            + "PRIMARY KEY (`id`,`id2`))");
+
+    stmt = sharedConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
+    stmt.execute("INSERT INTO testDelete values (1,-1,'1'), (2,-2,'2'), (3,-3,'3')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT * FROM testDelete", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      assertThrows(SQLException.class, rs::deleteRow);
+      assertTrue(rs.next());
+      assertTrue(rs.next());
+      assertEquals(2, rs.getInt(1));
+      rs.deleteRow();
+      assertEquals(1, rs.getInt(1));
+      assertEquals(-1, rs.getInt(2));
+      assertTrue(rs.next());
+      assertEquals(3, rs.getInt(1));
+      assertEquals(-3, rs.getInt(2));
+    }
+
+    ResultSet rs = stmt.executeQuery("SELECT * FROM testDelete");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals(-1, rs.getInt(2));
+    assertTrue(rs.next());
+    assertEquals(3, rs.getInt(1));
+    assertEquals(-3, rs.getInt(2));
+    assertFalse(rs.next());
+
+    rs.absolute(1);
+    rs.deleteRow();
+    Common.assertThrowsContains(SQLException.class, () -> rs.getInt(1), "wrong row position");
+  }
+
+  @Test
+  public void testUpdateChangingMultiplePrimaryKey() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS testUpdateChangingMultiplePrimaryKey");
+    stmt.execute(
+        "CREATE TABLE testUpdateChangingMultiplePrimaryKey("
+            + "`id` INT NOT NULL,"
+            + "`id2` INT NOT NULL,"
+            + "`t1` VARCHAR(50),"
+            + "PRIMARY KEY (`id`,`id2`))");
+    stmt.execute(
+        "INSERT INTO testUpdateChangingMultiplePrimaryKey values (1,-1,'1'), (2,-2,'2'),"
+            + " (3,-3,'3')");
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT * FROM testUpdateChangingMultiplePrimaryKey",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+
+      assertTrue(rs.next());
+      assertTrue(rs.next());
+      rs.updateInt(1, 4);
+      rs.updateInt(2, -4);
+      rs.updateString(3, "4");
+      rs.updateRow();
+
+      assertEquals(4, rs.getInt(1));
+      assertEquals(-4, rs.getInt(2));
+      assertEquals("4", rs.getString(3));
+    }
+
+    ResultSet rs = stmt.executeQuery("SELECT * FROM testUpdateChangingMultiplePrimaryKey");
+
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals(-1, rs.getInt(2));
+    assertEquals("1", rs.getString(3));
+
+    assertTrue(rs.next());
+    assertEquals(3, rs.getInt(1));
+    assertEquals(-3, rs.getInt(2));
+    assertEquals("3", rs.getString(3));
+
+    assertTrue(rs.next());
+    assertEquals(4, rs.getInt(1));
+    assertEquals(-4, rs.getInt(2));
+    assertEquals("4", rs.getString(3));
+
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void updateBlobClob() throws SQLException, IOException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS updateBlob");
+    stmt.execute("CREATE TABLE updateBlob(id int not null primary key, strm blob)");
+    stmt.execute("START TRANSACTION ");
+    try {
+      PreparedStatement prep =
+          sharedConn.prepareStatement("insert into updateBlob (id, strm) values (?,?)");
+      byte[] theBlob = {1, 2, 3, 4, 5, 6};
+      InputStream stream = new ByteArrayInputStream(theBlob);
+
+      prep.setInt(1, 1);
+      prep.setBlob(2, stream);
+      prep.execute();
+
+      byte[] updatedBlob = "abcdef".getBytes(StandardCharsets.UTF_8);
+
+      try (PreparedStatement preparedStatement =
+          sharedConn.prepareStatement(
+              "select * from updateBlob",
+              ResultSet.TYPE_FORWARD_ONLY,
+              ResultSet.CONCUR_UPDATABLE)) {
+        ResultSet rs = preparedStatement.executeQuery();
+        assertTrue(rs.next());
+
+        rs.updateBlob(2, new ByteArrayInputStream(updatedBlob));
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateBlob("strm", new ByteArrayInputStream(updatedBlob));
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateBlob(2, new ByteArrayInputStream(updatedBlob), 20L);
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateBlob("strm", new ByteArrayInputStream(updatedBlob), 20L);
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateClob(2, new StringReader("abcdef"));
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateClob("strm", new StringReader("abcdef"));
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateClob(2, new StringReader("abcdef"), 20L);
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateClob("strm", new StringReader("abcdef"), 20L);
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateNClob(2, new StringReader("abcdef"));
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateNClob("strm", new StringReader("abcdef"));
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateNClob(2, new StringReader("abcdef"), 20L);
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+
+        rs.updateNClob("strm", new StringReader("abcdef"), 20L);
+        rs.updateRow();
+        checkResult(rs, updatedBlob);
+      }
+
+      try (PreparedStatement preparedStatement =
+          sharedConn.prepareStatement(
+              "select * from updateBlob",
+              ResultSet.TYPE_FORWARD_ONLY,
+              ResultSet.CONCUR_UPDATABLE)) {
+        ResultSet rs = preparedStatement.executeQuery();
+        assertTrue(rs.next());
+        checkResult(rs, updatedBlob);
+      }
+    } finally {
+      sharedConn.rollback();
+    }
+  }
+
+  private void checkResult(ResultSet rs, byte[] updatedBlob) throws SQLException, IOException {
+    InputStream readStuff = rs.getBlob("strm").getBinaryStream();
+    int ch;
+    int pos = 0;
+    while ((ch = readStuff.read()) != -1) {
+      assertEquals(updatedBlob[pos++], ch);
+    }
+
+    readStuff = rs.getBinaryStream("strm");
+
+    pos = 0;
+    while ((ch = readStuff.read()) != -1) {
+      assertEquals(updatedBlob[pos++], ch);
+    }
+  }
+
+  @Test
+  public void updateMeta() throws SQLException {
+    DatabaseMetaData meta = sharedConn.getMetaData();
+
+    assertTrue(meta.ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY));
+    assertTrue(meta.ownDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY));
+    assertTrue(meta.ownInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY));
+    assertTrue(
+        meta.supportsResultSetConcurrency(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY));
+    assertTrue(
+        meta.supportsResultSetConcurrency(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE));
+
+    assertTrue(meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE));
+    assertTrue(meta.ownDeletesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE));
+    assertTrue(meta.ownInsertsAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE));
+    assertTrue(
+        meta.supportsResultSetConcurrency(
+            ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY));
+    assertTrue(
+        meta.supportsResultSetConcurrency(
+            ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE));
+
+    assertFalse(meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE));
+    assertFalse(meta.ownDeletesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE));
+    assertFalse(meta.ownInsertsAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE));
+    assertFalse(
+        meta.supportsResultSetConcurrency(
+            ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY));
+    assertFalse(
+        meta.supportsResultSetConcurrency(
+            ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE));
+  }
+
+  @Test
+  public void updateResultSetMeta() throws SQLException {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    assertEquals(ResultSet.CONCUR_READ_ONLY, stmt.getResultSetConcurrency());
+    ResultSet rs = stmt.executeQuery("SELECT 1");
+    assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency());
+
+    stmt = sharedConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
+    assertEquals(ResultSet.CONCUR_UPDATABLE, stmt.getResultSetConcurrency());
+    rs = stmt.executeQuery("SELECT 1");
+    assertEquals(ResultSet.CONCUR_UPDATABLE, rs.getConcurrency());
+  }
+
+  @Test
+  public void insertNoRow() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS insertNoRow");
+    stmt.execute("CREATE TABLE insertNoRow(id int not null primary key, strm blob)");
+    java.sql.Statement st =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
+    ResultSet rs = st.executeQuery("select * from insertNoRow");
+    assertFalse(rs.next());
+    rs.moveToInsertRow();
+    try {
+      rs.refreshRow();
+      fail("Can't refresh when on the insert row.");
+    } catch (SQLException sqle) {
+      // expected
+    }
+    rs.moveToCurrentRow();
+  }
+
+  @Test
+  public void refreshRow() throws SQLException {
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts=false")) {
+      refreshRow(con);
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts")) {
+      refreshRow(con);
+    }
+  }
+
+  private void refreshRow(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS refreshRow");
+    stmt.execute("CREATE TABLE refreshRow(id int not null primary key, strm text)");
+
+    java.sql.Statement st =
+        con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
+    st.execute("INSERT INTO refreshRow values (1, '555')");
+    ResultSet rs = st.executeQuery("select * from refreshRow");
+
+    st.execute("UPDATE refreshRow set strm = '666' WHERE id = 1");
+    try {
+      rs.refreshRow();
+      fail("Can't refresh when not on row.");
+    } catch (SQLException sqle) {
+      // expected
+    }
+
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertEquals("555", rs.getString(2));
+    rs.refreshRow();
+    assertEquals("666", rs.getString(2));
+
+    rs.moveToInsertRow();
+    assertThrows(SQLException.class, rs::refreshRow);
+    rs.moveToCurrentRow();
+
+    assertFalse(rs.next());
+    assertThrows(SQLException.class, rs::refreshRow);
+  }
+
+  @Test
+  public void testMoveToInsertRow() throws SQLException {
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts=false")) {
+      testMoveToInsertRow(con);
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts")) {
+      testMoveToInsertRow(con);
+    }
+  }
+
+  private void testMoveToInsertRow(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS testMoveToInsertRow");
+    stmt.execute("CREATE TABLE testMoveToInsertRow(t2 text, t1 text, id int primary key)");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select id, t1, t2 from testMoveToInsertRow",
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+
+      assertNotNull(rs);
+      assertEquals(0, rs.getRow());
+      rs.moveToInsertRow();
+      rs.updateInt(1, 1);
+      rs.updateString(2, "t1-value");
+      rs.updateString(3, "t2-value");
+      rs.insertRow();
+      rs.first();
+      assertEquals(1, rs.getRow());
+
+      rs.updateInt("id", 2);
+      rs.updateString("t1", "t1-bis-value");
+      rs.updateRow();
+      assertEquals(1, rs.getRow());
+
+      assertEquals(2, rs.getInt("id"));
+      assertEquals("t1-bis-value", rs.getString("t1"));
+      assertEquals("t2-value", rs.getString("t2"));
+
+      rs.deleteRow();
+      assertEquals(0, rs.getRow());
+
+      rs.moveToInsertRow();
+      rs.updateInt("id", 3);
+      rs.updateString("t1", "other-t1-value");
+      Common.assertThrowsContains(
+          SQLException.class, rs::refreshRow, "Cannot call refreshRow() when inserting a new row");
+
+      rs.insertRow();
+      assertEquals(0, rs.getRow());
+      rs.next();
+      assertEquals(3, rs.getInt("id"));
+      assertEquals("other-t1-value", rs.getString("t1"));
+      assertNull(rs.getString("t2"));
+    } finally {
+      con.commit();
+    }
+
+    stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "select id, t1, t2 from testMoveToInsertRow",
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+
+      assertTrue(rs.first());
+      assertEquals(1, rs.getRow());
+      rs.updateInt("id", 3);
+      rs.updateString("t1", "t1-3");
+      rs.updateRow();
+      assertEquals(1, rs.getRow());
+
+      assertEquals(3, rs.getInt("id"));
+      assertEquals("t1-3", rs.getString("t1"));
+
+      rs.moveToInsertRow();
+      rs.updateInt("id", 4);
+      rs.updateString("t1", "t1-4");
+      rs.insertRow();
+      assertEquals(1, rs.getRow());
+
+      rs.updateInt("id", 5);
+      rs.updateString("t1", "t1-5");
+      rs.insertRow();
+      assertEquals(1, rs.getRow());
+
+      rs.moveToCurrentRow();
+      assertEquals(3, rs.getInt("id"));
+      assertEquals("t1-3", rs.getString("t1"));
+
+      assertTrue(rs.next());
+      assertEquals(4, rs.getInt("id"));
+      assertEquals("t1-4", rs.getString("t1"));
+
+      assertTrue(rs.next());
+      assertEquals(5, rs.getInt("id"));
+      assertEquals("t1-5", rs.getString("t1"));
+    } finally {
+      sharedConn.rollback();
+    }
+  }
+
+  @Test
+  public void cancelRowUpdatesTest() throws SQLException {
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts=false")) {
+      cancelRowUpdatesTest(con);
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts")) {
+      cancelRowUpdatesTest(con);
+    }
+  }
+
+  private void cancelRowUpdatesTest(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS cancelRowUpdatesTest");
+    stmt.execute("CREATE TABLE cancelRowUpdatesTest(c text, id int primary key)");
+    stmt.execute("INSERT INTO cancelRowUpdatesTest(id,c) values (1,'1'), (2,'2'),(3,'3'),(4,'4')");
+    stmt.execute("FLUSH TABLES");
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select id,c from cancelRowUpdatesTest order by id",
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+
+      assertTrue(rs.next());
+      assertTrue(rs.next());
+
+      assertEquals("2", rs.getString("c"));
+      rs.updateString("c", "2bis");
+      rs.cancelRowUpdates();
+      rs.updateRow();
+      assertEquals("2", rs.getString("c"));
+
+      rs.updateString("c", "2bis");
+      rs.updateRow();
+      assertEquals("2bis", rs.getString("c"));
+
+      assertTrue(rs.first());
+      assertTrue(rs.next());
+      assertEquals("2bis", rs.getString("c"));
+    }
+  }
+
+  @Test
+  public void deleteRowsTest() throws SQLException {
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts=false")) {
+      deleteRowsTest(con);
+    }
+    try (org.mariadb.jdbc.Connection con = createCon("&useServerPrepStmts")) {
+      deleteRowsTest(con);
+    }
+  }
+
+  private void deleteRowsTest(Connection con) throws SQLException {
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS deleteRows");
+    stmt.execute("CREATE TABLE deleteRows(c text, id int primary key)");
+    stmt.execute("INSERT INTO deleteRows(id,c) values (1,'1'), (2,'2'),(3,'3'),(4,'4')");
+
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select id,c from deleteRows order by id",
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+
+      assertTrue(rs.next());
+      assertEquals(1, rs.getInt("id"));
+
+      rs.deleteRow();
+
+      assertTrue(rs.isBeforeFirst());
+
+      assertTrue(rs.next());
+      assertTrue(rs.next());
+      assertEquals(3, rs.getInt("id"));
+
+      rs.deleteRow();
+      assertEquals(2, rs.getInt("id"));
+    }
+  }
+
+  @Test
+  public void updatePosTest() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS updatePosTest");
+    stmt.execute("CREATE TABLE updatePosTest(c text, id int primary key)");
+    stmt.execute("INSERT INTO updatePosTest(id,c) values (1,'1')");
+
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "select id,c from updatePosTest",
+            ResultSet.TYPE_SCROLL_INSENSITIVE,
+            ResultSet.CONCUR_UPDATABLE)) {
+
+      ResultSet rs = preparedStatement.executeQuery();
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> rs.updateInt(1, 20),
+          "Current position is before the first row");
+      Common.assertThrowsContains(
+          SQLException.class, rs::updateRow, "Current position is before the first row");
+      Common.assertThrowsContains(
+          SQLException.class, rs::deleteRow, "Current position is before the first row");
+
+      assertTrue(rs.next());
+      rs.updateInt(1, 20);
+      rs.updateNull(2);
+      rs.updateRow();
+      rs.deleteRow();
+      assertFalse(rs.next());
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateInt(1, 20), "Current position is after the last row");
+      Common.assertThrowsContains(
+          SQLException.class, rs::updateRow, "Current position is after the last row");
+      Common.assertThrowsContains(
+          SQLException.class, rs::deleteRow, "Current position is after the last row");
+    }
+  }
+
+  /**
+   * CONJ-519 : Updatable result-set possible NPE when same field is repeated.
+   *
+   * @throws SQLException if any exception occur
+   */
+  @Test
+  public void repeatedFieldUpdatable() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS repeatedFieldUpdatable");
+    stmt.execute(
+        "CREATE TABLE repeatedFieldUpdatable(t1 varchar(50) NOT NULL, t2 varchar(50), PRIMARY KEY"
+            + " (t1))");
+    stmt.execute("insert into repeatedFieldUpdatable values ('gg', 'hh'), ('jj', 'll')");
+
+    PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT t1, t2, t1 as t3 FROM repeatedFieldUpdatable",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE);
+    ResultSet rs = preparedStatement.executeQuery();
+    while (rs.next()) {
+      rs.getObject(3);
+    }
+  }
+
+  @Test
+  public void updatableDefaultPrimaryField() throws SQLException {
+    Assumptions.assumeTrue(isMariaDBServer() && minVersion(10, 2, 0));
+    String sql = "SELECT t.* FROM testDefaultUUID t WHERE 1 = 2";
+    try (PreparedStatement pstmt =
+        sharedConn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
+      pstmt.execute();
+      ResultSet rs = pstmt.getResultSet();
+      rs.moveToInsertRow();
+      rs.updateString("column2", "x");
+      try {
+        rs.insertRow();
+        if (!isMariaDBServer() || !minVersion(10, 5, 3)) {
+          fail("Must have thrown exception");
+        }
+        rs.next();
+        assertEquals(36, rs.getString(1).length());
+        assertEquals("x", rs.getString(2));
+      } catch (SQLException e) {
+        if (isMariaDBServer() && minVersion(10, 5, 3)) {
+          fail("Must have succeed");
+        }
+        assertTrue(
+            e.getMessage()
+                .contains(
+                    "Cannot call insertRow() not setting value for primary key column1 with "
+                        + "default value before server 10.5"));
+      }
+      rs.moveToInsertRow();
+      rs.updateString("column1", "de6f7774-e399-11ea-aa68-c8348e0fed44");
+      rs.updateString("column2", "x");
+      rs.insertRow();
+      rs.next();
+      assertEquals("de6f7774-e399-11ea-aa68-c8348e0fed44", rs.getString(1));
+      assertEquals("x", rs.getString(2));
+    }
+  }
+
+  @Test
+  public void expectedErrorField() throws SQLException {
+    Assumptions.assumeTrue(isMariaDBServer() && minVersion(10, 2, 0));
+    String sql = "SELECT * FROM testExpError t WHERE 1 = 2";
+    try (PreparedStatement pstmt =
+        sharedConn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
+      pstmt.execute();
+      ResultSet rs = pstmt.getResultSet();
+      rs.moveToInsertRow();
+      Common.assertThrowsContains(SQLException.class, () -> rs.updateRef(2, null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateRef("t1", null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateArray(2, null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateArray("t1", null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateRowId(2, null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateRowId("t1", null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateSQLXML(2, null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, () -> rs.updateSQLXML("t1", null), "not supported");
+      Common.assertThrowsContains(
+          SQLException.class, rs::deleteRow, "Cannot call deleteRow() when inserting a new row");
+      Common.assertThrowsContains(
+          SQLException.class, rs::updateRow, "Cannot call updateRow() when inserting a new row");
+    }
+  }
+
+  @Test
+  public void addAfterDataFull() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "INSERT INTO test_update_max(t1) value ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'),"
+            + " ('8'), ('9'), ('10')");
+    try (PreparedStatement preparedStatement =
+        sharedConn.prepareStatement(
+            "SELECT t1, id FROM test_update_max",
+            ResultSet.TYPE_FORWARD_ONLY,
+            ResultSet.CONCUR_UPDATABLE)) {
+      ResultSet rs = preparedStatement.executeQuery();
+      rs.moveToInsertRow();
+      rs.updateString("t1", "11");
+      rs.insertRow();
+      for (int i = 0; i < 11; i++) rs.next();
+      assertEquals("11", rs.getString("t1"));
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/XaTest.java b/src/test/java/org/mariadb/jdbc/integration/XaTest.java
new file mode 100644
index 0000000..af35bc1
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/XaTest.java
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import java.sql.Connection;
+import java.util.UUID;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import org.junit.jupiter.api.*;
+import org.mariadb.jdbc.*;
+import org.mariadb.jdbc.Statement;
+
+public class XaTest extends Common {
+
+  private static MariaDbDataSource dataSource;
+  private static MariaDbPoolDataSource poolDataSource;
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS xatable");
+    if (poolDataSource != null) poolDataSource.close();
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    Assumptions.assumeTrue(
+        !"skysql".equals(System.getenv("srv"))
+            && !"skysql-ha".equals(System.getenv("srv"))
+            && !isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS xatable");
+    stmt.execute("CREATE TABLE xatable(i int)");
+    stmt.execute("FLUSH TABLES");
+    dataSource = new MariaDbDataSource(mDefUrl);
+    poolDataSource = new MariaDbPoolDataSource(mDefUrl);
+  }
+
+  @Test
+  public void xidToString() {
+    MariaDbXid xid = new MariaDbXid(1575, new byte[] {0x00}, new byte[] {0x01});
+    assertEquals("0x00,0x01,0x627", MariaDbPoolConnection.xidToString(xid));
+    assertEquals(
+        "0x00,0x,0x627",
+        MariaDbPoolConnection.xidToString(new MariaDbXid(1575, new byte[] {0x00}, null)));
+    assertEquals(
+        "0x,0x000100,0x400",
+        MariaDbPoolConnection.xidToString(
+            new MariaDbXid(1024, new byte[] {}, new byte[] {0x00, 0x01, 0x00})));
+    assertEquals(
+        "0x00,0x000100,0xc3c20186",
+        MariaDbPoolConnection.xidToString(
+            new MariaDbXid(-1010695802, new byte[] {0x00}, new byte[] {0x00, 0x01, 0x00})));
+    assertEquals(xid, xid);
+    assertEquals(xid, new MariaDbXid(1575, new byte[] {0x00}, new byte[] {0x01}));
+    assertFalse(xid.equals("dd"));
+    assertFalse(xid.equals(null));
+    assertEquals(1544359, xid.hashCode());
+  }
+
+  @Test
+  public void xaRmTest() throws Exception {
+    MariaDbDataSource dataSource1 = new MariaDbDataSource(mDefUrl);
+    MariaDbDataSource dataSource2 = new MariaDbDataSource(mDefUrl + "&test=t");
+    XAConnection con1 = dataSource1.getXAConnection();
+    XAConnection con2 = dataSource1.getXAConnection();
+    XAConnection con3 = dataSource2.getXAConnection();
+    assertTrue(con1.getXAResource().isSameRM(con1.getXAResource()));
+    assertTrue(con1.getXAResource().isSameRM(con2.getXAResource()));
+    assertFalse(con1.getXAResource().isSameRM(con3.getXAResource()));
+
+    assertEquals(0, con1.getXAResource().getTransactionTimeout());
+    con1.getXAResource().setTransactionTimeout(10);
+    assertEquals(0, con1.getXAResource().getTransactionTimeout());
+    Xid xid = new MariaDbXid(1575, new byte[] {0x00}, new byte[] {0x01});
+    con1.getXAResource().forget(xid);
+    assertThrows(XAException.class, () -> con1.getXAResource().end(xid, XAResource.TMENDRSCAN));
+    assertThrows(XAException.class, () -> con1.getXAResource().start(xid, XAResource.TMSUCCESS));
+
+    con1.close();
+    con2.close();
+    con3.close();
+  }
+
+  private Xid newXid() {
+    return new MariaDbXid(
+        1, UUID.randomUUID().toString().getBytes(), UUID.randomUUID().toString().getBytes());
+  }
+
+  private Xid newXid(Xid branchFrom) {
+    return new MariaDbXid(
+        1, branchFrom.getGlobalTransactionId(), UUID.randomUUID().toString().getBytes());
+  }
+
+  /**
+   * 2 phase commit , with either commit or rollback at the end.
+   *
+   * @param doCommit must commit
+   * @throws Exception exception
+   */
+  private int test2PhaseCommit(boolean doCommit, XADataSource dataSource) throws Exception {
+
+    int connectionNumber = 2;
+
+    Xid parentXid = newXid();
+    java.sql.Connection[] connections = new java.sql.Connection[connectionNumber];
+    XAConnection[] xaConnections = new XAConnection[connectionNumber];
+    XAResource[] xaResources = new XAResource[connectionNumber];
+    Xid[] xids = new Xid[connectionNumber];
+
+    try {
+
+      for (int i = 0; i < connectionNumber; i++) {
+        if (i == 0) {
+          xaConnections[i] = dataSource.getXAConnection(user, password);
+        } else xaConnections[i] = dataSource.getXAConnection();
+
+        connections[i] = xaConnections[i].getConnection();
+        xaResources[i] = xaConnections[i].getXAResource();
+        xids[i] = newXid(parentXid);
+      }
+
+      startAllResources(connectionNumber, xaResources, xids);
+      insertDatas(connectionNumber, connections);
+      endAllResources(connectionNumber, xaResources, xids);
+      prepareAllResources(connectionNumber, xaResources, xids);
+
+      for (int i = 0; i < connectionNumber; i++) {
+        if (doCommit) {
+          xaResources[i].commit(xids[i], false);
+        } else {
+          xaResources[i].rollback(xids[i]);
+        }
+      }
+
+    } finally {
+      for (int i = 0; i < connectionNumber; i++) {
+        try {
+          if (xaConnections[i] != null) {
+            xaConnections[i].getConnection().close();
+          }
+        } catch (Exception e) {
+          e.printStackTrace();
+        }
+      }
+    }
+    return connectionNumber;
+  }
+
+  private void startAllResources(int connectionNumber, XAResource[] xaResources, Xid[] xids)
+      throws XAException {
+    for (int i = 0; i < connectionNumber; i++) {
+      xaResources[i].start(xids[i], XAResource.TMNOFLAGS);
+    }
+  }
+
+  private void endAllResources(int connectionNumber, XAResource[] xaResources, Xid[] xids)
+      throws XAException {
+    for (int i = 0; i < connectionNumber; i++) {
+      xaResources[i].end(xids[i], XAResource.TMSUCCESS);
+    }
+  }
+
+  private void prepareAllResources(int connectionNumber, XAResource[] xaResources, Xid[] xids)
+      throws XAException {
+    for (int i = 0; i < connectionNumber; i++) {
+      xaResources[i].prepare(xids[i]);
+    }
+  }
+
+  private void insertDatas(int connectionNumber, java.sql.Connection[] connections)
+      throws SQLException {
+    for (int i = 0; i < connectionNumber; i++) {
+      connections[i].createStatement().executeUpdate("INSERT INTO xatable VALUES (" + i + ")");
+    }
+  }
+
+  @Test
+  public void testCommit() throws Exception {
+    Assumptions.assumeFalse("galera".equals(System.getenv("srv")));
+    testCommit(dataSource);
+    testCommit(poolDataSource);
+  }
+
+  public void testCommit(XADataSource dataSource) throws Exception {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE xatable");
+    int connectionNumber = test2PhaseCommit(true, dataSource);
+
+    // check the completion
+    ResultSet rs = stmt.executeQuery("SELECT * from xatable order by i");
+    for (int i = 0; i < connectionNumber; i++) {
+      assertTrue(rs.next());
+      assertEquals(rs.getInt(1), i);
+    }
+  }
+
+  @Test
+  public void testRollback() throws Exception {
+    Assumptions.assumeFalse("galera".equals(System.getenv("srv")));
+    testRollback(dataSource);
+    testRollback(poolDataSource);
+  }
+
+  public void testRollback(XADataSource dataSource) throws Exception {
+    java.sql.Statement stmt = sharedConn.createStatement();
+    stmt.execute("TRUNCATE xatable");
+    test2PhaseCommit(false, dataSource);
+    // check the completion
+    ResultSet rs = stmt.executeQuery("SELECT * from xatable order by i");
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void testRecover() throws Exception {
+    Assumptions.assumeFalse("galera".equals(System.getenv("srv")));
+    XAConnection xaConnection = dataSource.getXAConnection();
+    try {
+      java.sql.Connection connection = xaConnection.getConnection();
+      Xid xid = newXid();
+      XAResource xaResource = xaConnection.getXAResource();
+      xaResource.start(xid, XAResource.TMNOFLAGS);
+      connection.createStatement().executeQuery("SELECT 1");
+      xaResource.end(xid, XAResource.TMSUCCESS);
+      xaResource.prepare(xid);
+      Xid[] recoveredXids = xaResource.recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN);
+      assertTrue(recoveredXids != null);
+      assertTrue(recoveredXids.length > 0);
+      boolean found = false;
+
+      for (Xid x : recoveredXids) {
+        if (x != null && x.equals(xid)) {
+          found = true;
+          break;
+        }
+      }
+      assertTrue(found);
+    } finally {
+      xaConnection.close();
+    }
+  }
+
+  @Test
+  public void resumeAndJoinTest() throws Exception {
+    Assumptions.assumeFalse("galera".equals(System.getenv("srv")));
+    Connection conn1;
+    MariaDbDataSource ds = new MariaDbDataSource(mDefUrl);
+
+    XAConnection xaConn1 = null;
+    Xid xid = newXid();
+    try {
+      xaConn1 = ds.getXAConnection();
+      XAResource xaRes1 = xaConn1.getXAResource();
+      conn1 = xaConn1.getConnection();
+      xaRes1.start(xid, XAResource.TMNOFLAGS);
+      conn1.createStatement().executeQuery("SELECT 1");
+      xaRes1.end(xid, XAResource.TMSUCCESS);
+      xaRes1.start(xid, XAResource.TMRESUME);
+      conn1.createStatement().executeQuery("SELECT 1");
+      xaRes1.end(xid, XAResource.TMSUCCESS);
+      xaRes1.commit(xid, true);
+      xaConn1.close();
+
+      xaConn1 = ds.getXAConnection();
+      xaRes1 = xaConn1.getXAResource();
+      conn1 = xaConn1.getConnection();
+      xaRes1.start(xid, XAResource.TMNOFLAGS);
+      conn1.createStatement().executeQuery("SELECT 1");
+      xaRes1.end(xid, XAResource.TMSUCCESS);
+      try {
+        xaRes1.start(xid, XAResource.TMJOIN);
+        fail(); // without pinGlobalTxToPhysicalConnection=true
+      } catch (XAException xaex) {
+        xaConn1.close();
+      }
+
+    } finally {
+      if (xaConn1 != null) {
+        xaConn1.close();
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/BinaryCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/BinaryCodecTest.java
new file mode 100644
index 0000000..33bdf74
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/BinaryCodecTest.java
@@ -0,0 +1,834 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class BinaryCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS BinaryCodec");
+    stmt.execute("DROP TABLE IF EXISTS BinaryCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE BinaryCodec (t1 VARBINARY(20), t2 VARBINARY(30), t3 VARBINARY(20), t4"
+            + " BINARY(20)) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+    stmt.execute(
+        "INSERT INTO BinaryCodec VALUES ('0', '1', 'some🌟', null), ('2011-01-01', '2010-12-31"
+            + " 23:59:59.152', '23:54:51.840010', null)");
+    stmt.execute(
+        "CREATE TABLE BinaryCodec2 (id int not null primary key auto_increment, t1 VARBINARY(20))");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from BinaryCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement prepareStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from BinaryCodec"
+                + " WHERE 1 > ?");
+    prepareStatement.closeOnCompletion();
+    prepareStatement.setInt(1, 0);
+    ResultSet rs = prepareStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertArrayEquals("0".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(2));
+    assertArrayEquals("1".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testArrObject(rs, new byte[] {(byte) '0'});
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testObject(rs, Clob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, NClob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, InputStream.class, new MariaDbClob("0".getBytes()).getBinaryStream());
+    testObject(rs, Reader.class, new StringReader("0"));
+    rs.next();
+    testObject(rs, LocalDate.class, LocalDate.parse("2011-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2011-01-01T00:00"));
+    testObject(rs, LocalTime.class, LocalTime.parse("23:54:51.840010"), 3);
+    Time t = Time.valueOf("23:54:51");
+    testObject(rs, Time.class, new Time(t.getTime() + 840), 3);
+    testObject(rs, Date.class, Date.valueOf("2011-01-01"));
+    Timestamp tt = Timestamp.valueOf("2010-12-31 23:59:59");
+    testObject(rs, Timestamp.class, new Timestamp(tt.getTime() + 152), 2);
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2011-01-01T00:00").atZone(ZoneId.systemDefault()));
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getByte(3),
+        "value 'some\uD83C\uDF1F' (VARSTRING) cannot be decoded as Byte");
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getShort(3), "value 'some🌟' cannot be decoded as Short");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(3), "value 'some🌟' cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getLong(3),
+        "value 'some\uD83C\uDF1F' cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(3), "value 'some🌟' cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(3),
+        "value 'some🌟' cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(3),
+        "value 'some🌟' cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(1),
+        "value '0' (VARSTRING) cannot be decoded as Date");
+    rs.next();
+    assertEquals("2011-01-01", rs.getDate(1).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate(2).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate("t2alias").toString());
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(3),
+        "value '23:54:51.840010' (VARSTRING) cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "value '2011-01-01' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(2),
+        "value '2010-12-31 23:59:59.152' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(3).getTime());
+    assertEquals(
+        86091840, rs.getTime(3, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime("t3alias").getTime());
+    assertEquals(
+        86091840,
+        rs.getTime("t3alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    rs.next();
+
+    assertEquals(Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152, rs.getTimestamp(2).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152,
+        rs.getTimestamp("t2alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t2alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    //
+    //    ('2011-01-01', '2010-12-31 23:59:59.152',"
+    //            + " '23:54:51.840010', null)
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "cannot be decoded as OffsetDateTime");
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getAsciiStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getAsciiStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getAsciiStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getUnicodeStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)),
+        rs.getUnicodeStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getUnicodeStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getBinaryStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBinaryStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBinaryStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws Exception {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws Exception {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) throws Exception {
+    assertArrayEquals("0".getBytes(), rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(), rs.getBytes(2));
+    assertArrayEquals("1".getBytes(), rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBytes(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getNCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getNCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbBlob("0".getBytes()), rs.getBlob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), rs.getBlob(2));
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), rs.getBlob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbBlob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBlob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBlob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getNClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getNClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("VARBINARY", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("byte[]", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(20, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(20, meta.getColumnDisplaySize(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(4));
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+
+    try (Connection con = createCon("transactionReplay=true&useServerPrepStmts=false")) {
+      sendParam(con);
+    }
+    try (Connection con = createCon("transactionReplay=true&useServerPrepStmts=true")) {
+      sendParam(con);
+    }
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE BinaryCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO BinaryCodec2(t1) VALUES (?)")) {
+      prep.setClob(1, new MariaDbClob("e🌟1".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setClob(1, (Clob) null);
+      prep.execute();
+      prep.setObject(1, new MariaDbClob("e🌟2".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, new MariaDbClob("e🌟3".getBytes(StandardCharsets.UTF_8)), Types.CLOB);
+      prep.execute();
+      prep.setObject(1, null, Types.CLOB);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM BinaryCodec2");
+
+    assertTrue(rs.next());
+    assertEquals("e🌟1", rs.getClob(2).toString());
+    rs.updateClob(2, new MariaDbClob("f🌟1".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("f🌟1", rs.getClob(2).toString());
+
+    assertTrue(rs.next());
+    assertNull(rs.getClob(2));
+    rs.updateObject(2, new MariaDbClob("f🌟2".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("f🌟2", rs.getClob(2).toString());
+
+    assertTrue(rs.next());
+    assertEquals("e🌟2", rs.getClob(2).toString());
+    rs.updateClob("t1", (Clob) null);
+    rs.updateRow();
+    assertNull(rs.getClob(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getClob(2));
+    rs.updateObject("t1", new MariaDbClob("f🌟3".getBytes(StandardCharsets.UTF_8)), Types.CLOB);
+    rs.updateRow();
+    assertEquals("f🌟3", rs.getClob(2).toString());
+
+    assertTrue(rs.next());
+    assertEquals("e🌟3", rs.getClob(2).toString());
+    rs.updateObject(2, null, Types.CLOB);
+    rs.updateRow();
+    assertNull(rs.getClob(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getClob(2));
+
+    rs = stmt.executeQuery("SELECT * FROM BinaryCodec2");
+    assertTrue(rs.next());
+    assertEquals("f🌟1", rs.getClob(2).toString());
+    assertTrue(rs.next());
+    assertEquals("f🌟2", rs.getClob(2).toString());
+    assertTrue(rs.next());
+    assertNull(rs.getClob(2));
+    assertTrue(rs.next());
+    assertEquals("f🌟3", rs.getClob(2).toString());
+    assertTrue(rs.next());
+    assertNull(rs.getClob(2));
+    assertTrue(rs.next());
+    assertNull(rs.getClob(2));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/BitCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/BitCodecTest.java
new file mode 100644
index 0000000..23299a0
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/BitCodecTest.java
@@ -0,0 +1,746 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import java.util.BitSet;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class BitCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS BitCodec");
+    stmt.execute("DROP TABLE IF EXISTS BitCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE BitCodec (t1 BIT(1), t2 BIT(4), t3 BIT(16), t4 BIT(24))");
+    stmt.execute("INSERT INTO BitCodec VALUES (b'0000', b'0001', b'0000111100000100', null)");
+    stmt.execute("CREATE TABLE BitCodec2 (id int not null primary key auto_increment, t1 BIT(16))");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from BitCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from BitCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals(false, rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals(new byte[] {(byte) 1}, (byte[]) rs.getObject(2));
+    assertArrayEquals(new byte[] {(byte) 1}, (byte[]) rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals(new byte[] {(byte) 15, (byte) 4}, (byte[]) rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, Byte.class, Byte.valueOf("0"));
+    testObject(rs, String.class, "b''");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BitSet.class, BitSet.valueOf(new byte[] {(byte) 0}));
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Boolean.class, Boolean.FALSE);
+
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testObject(rs, Byte.class, (byte) 0);
+    testObject(rs, byte[].class, new byte[] {0});
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("b''", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("b'1'", rs.getString(2));
+    assertEquals("b'1'", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("b'111100000100'", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("b''", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("b'1'", rs.getNString(2));
+    assertEquals("b'1'", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("b'111100000100'", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 15, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(3844, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(3844, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(3844L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(1), "Data type BIT cannot be decoded as Float");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getFloat("t1alias"),
+        "Data type BIT cannot be decoded as Float");
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDouble(1), "Data type BIT cannot be decoded as Double");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble("t1alias"),
+        "Data type BIT cannot be decoded as Double");
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(3844), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type BIT cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type BIT cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type BIT cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type BIT cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type BIT cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type BIT cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "Type class java.time.OffsetDateTime not supported type for BIT type");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type BIT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type BIT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws SQLException {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type BIT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type BIT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws SQLException {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type BIT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type BIT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) throws SQLException {
+    assertArrayEquals(new byte[] {(byte) 0}, rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals(new byte[] {(byte) 1}, rs.getBytes(2));
+    assertArrayEquals(new byte[] {(byte) 1}, rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals(new byte[] {(byte) 15, (byte) 4}, rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws SQLException {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type BIT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type BIT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws SQLException {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type BIT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type BIT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) throws SQLException {
+
+    assertEquals(new MariaDbBlob(new byte[] {(byte) 0x00}), rs.getBlob(1));
+    assertFalse(rs.wasNull());
+    assertEquals(new MariaDbBlob(new byte[] {(byte) 0x01}), rs.getBlob(2));
+    assertEquals(new MariaDbBlob(new byte[] {0x01}), rs.getBlob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(new MariaDbBlob(new byte[] {(byte) 15, (byte) 4}), rs.getBlob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBlob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws SQLException {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type BIT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type BIT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws SQLException {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getNClob(1), "Data type BIT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type BIT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(get());
+  }
+
+  @Test
+  public void getURLPrepare() throws SQLException {
+    getURL(getPrepare(sharedConn));
+    getURL(getPrepare(sharedConnBinary));
+  }
+
+  public void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse 'b''' as URL");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse 'b''' as URL");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("BIT", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Boolean", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.BOOLEAN, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(1, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(1, meta.getColumnDisplaySize(1));
+
+    assertEquals("BIT", meta.getColumnTypeName(2));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(2));
+    assertEquals("byte[]", meta.getColumnClassName(2));
+    assertEquals("t2alias", meta.getColumnLabel(2));
+    assertEquals("t2", meta.getColumnName(2));
+    assertEquals(Types.VARBINARY, meta.getColumnType(2));
+    assertEquals(4, meta.getPrecision(2));
+    assertEquals(0, meta.getScale(2));
+    assertEquals("", meta.getSchemaName(2));
+    assertEquals(4, meta.getColumnDisplaySize(2));
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE BitCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO BitCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, BitSet.valueOf(new byte[] {0x00, 0x01}));
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, BitSet.valueOf(new byte[] {0x00, 0x02}), Types.BINARY);
+      prep.execute();
+      prep.setObject(1, null, Types.BINARY);
+      prep.execute();
+      prep.setObject(1, 0, Types.BIT);
+      prep.execute();
+      prep.setObject(1, 1, Types.BIT);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM BitCodec2");
+    assertTrue(rs.next());
+    assertEquals("b'100000000'", rs.getString(2));
+    rs.updateObject(2, BitSet.valueOf(new byte[] {0x02, 0x00}));
+    rs.updateRow();
+    assertEquals("b'10'", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBytes(2));
+    rs.updateObject(2, BitSet.valueOf(new byte[] {0x03, 0x00}), Types.BINARY);
+    rs.updateRow();
+    assertEquals("b'11'", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("b'1000000000'", rs.getString(2));
+    rs.updateObject(2, null);
+    rs.updateRow();
+    assertNull(rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBytes(2));
+    rs.updateObject("t1", BitSet.valueOf(new byte[] {0x04, 0x00}), Types.BINARY);
+    rs.updateRow();
+    assertEquals("b'100'", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("b''", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("b'1'", rs.getString(2));
+
+    rs = stmt.executeQuery("SELECT * FROM BitCodec2");
+    assertTrue(rs.next());
+    assertEquals("b'10'", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("b'11'", rs.getString(2));
+    assertTrue(rs.next());
+    assertNull(rs.getBytes(2));
+    assertTrue(rs.next());
+    assertEquals("b'100'", rs.getString(2));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/BlobCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/BlobCodecTest.java
new file mode 100644
index 0000000..95ecaa4
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/BlobCodecTest.java
@@ -0,0 +1,1071 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.time.*;
+import java.util.Arrays;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class BlobCodecTest extends CommonCodecTest {
+  private static File tmpFile;
+  private static final byte[] fileContent = new byte[11000];
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS BlobCodec");
+    stmt.execute("DROP TABLE IF EXISTS BlobCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE BlobCodec (t1 TINYBLOB, t2 TINYBLOB, t3 TINYBLOB, t4 TINYBLOB)");
+    stmt.execute(
+        "INSERT INTO BlobCodec VALUES ('0', '1', 'some🌟', null), "
+            + "('2011-01-01', '2010-12-31 23:59:59.152', '23:54:51.840010', null),"
+            + "('', '2010-12-31 23:59:59.152', '23:54:51.840010', null)");
+    stmt.execute("CREATE TABLE BlobCodec2 (id int not null primary key auto_increment, t1 BLOB)");
+    stmt.execute("FLUSH TABLES");
+
+    tmpFile = File.createTempFile("temp-file-name", ".tmp");
+    for (int i = 0; i < 11_000; i++) {
+      fileContent[i] = (byte) (i % 110 + 40);
+    }
+
+    try (FileOutputStream fos = new FileOutputStream(tmpFile)) {
+      fos.write(fileContent);
+    }
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from BlobCodec");
+    assertTrue(rs.next());
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from BlobCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbBlob("0".getBytes()), (Blob) rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), (Blob) rs.getObject(2));
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), (Blob) rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new MariaDbBlob("some🌟".getBytes(StandardCharsets.UTF_8)), (Blob) rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testObject(rs, String.class, "0");
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testObject(rs, Byte.class, (byte) '0');
+    testArrObject(rs, new byte[] {(byte) '0'});
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testObject(rs, InputStream.class, new MariaDbBlob("0".getBytes()).getBinaryStream());
+    testErrObject(rs, Reader.class);
+    rs.next();
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, LocalTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testErrObject(rs, java.util.Date.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBoolean(1),
+        "Data type BLOB cannot be decoded as Boolean");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 48, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 49, rs.getByte(2));
+    assertEquals((byte) 49, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 115, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getByte(1),
+        "empty String value cannot be decoded as Byte");
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getShort(1), "Data type BLOB cannot be decoded as Short");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(1), "Data type BLOB cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getLong(1), "Data type BLOB cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(1), "Data type BLOB cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(1),
+        "Data type BLOB cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(1),
+        "Data type BLOB cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getBigIntegerPrepare() throws SQLException {
+    getBigInteger(getPrepare(sharedConn));
+    getBigInteger(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigInteger(CompleteResult rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigInteger(1),
+        "Data type BLOB cannot be decoded as BigInteger");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(get());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPrepare(sharedConn));
+    getDuration(getPrepare(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, Duration.class),
+        "Data type BLOB cannot be decoded as Duration");
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type BLOB cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type BLOB cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type BLOB cannot be decoded as Timestamp");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "cannot be decoded as OffsetDateTime");
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getAsciiStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getAsciiStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getAsciiStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getUnicodeStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)),
+        rs.getUnicodeStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getUnicodeStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getBinaryStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBinaryStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBinaryStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws Exception {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws Exception {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) throws Exception {
+    assertArrayEquals("0".getBytes(), rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(), rs.getBytes(2));
+    assertArrayEquals("1".getBytes(), rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBytes(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) throws Exception {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type BLOB cannot be decoded as Reader");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) throws Exception {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type BLOB cannot be decoded as Reader");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbBlob("0".getBytes()), rs.getBlob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), rs.getBlob(2));
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), rs.getBlob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbBlob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBlob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBlob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) throws Exception {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type BLOB cannot be decoded as Clob");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) throws Exception {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getNClob(1), "Data type BLOB cannot be decoded as Clob");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("TINYBLOB", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.sql.Blob", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(255, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(255, meta.getColumnDisplaySize(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+
+    try (Connection con = createCon("transactionReplay=true&useServerPrepStmts=false")) {
+      sendParam(con);
+    }
+    try (Connection con = createCon("transactionReplay=true&useServerPrepStmts=true")) {
+      sendParam(con);
+    }
+    try (Connection con = createCon()) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("SET sql_mode = concat(@@sql_mode,',NO_BACKSLASH_ESCAPES')");
+      sendParam(con);
+    }
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE BlobCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO BlobCodec2(t1) VALUES (?)")) {
+      prep.setBlob(1, (Blob) null);
+      prep.execute();
+      prep.setBlob(1, new MariaDbBlob("e🌟1".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setBlob(1, (Blob) null);
+      prep.execute();
+      prep.setNull(1, Types.BLOB);
+      prep.execute();
+
+      prep.setObject(1, new MariaDbBlob("e🌟2".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setObject(1, new MariaDbBlob("e🌟2".getBytes(StandardCharsets.UTF_8)), Types.BLOB, 5);
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, new MariaDbBlob("e🌟3".getBytes(StandardCharsets.UTF_8)), Types.BLOB);
+      prep.execute();
+      prep.setObject(1, null, Types.BLOB);
+      prep.execute();
+
+      prep.setObject(1, new MariaDbBlob("e🌟4".getBytes(StandardCharsets.UTF_8)));
+      prep.addBatch();
+      prep.setObject(1, new MariaDbBlob("e🌟56".getBytes(StandardCharsets.UTF_8)), Types.BLOB, 6);
+      prep.addBatch();
+      prep.executeBatch();
+
+      try (FileInputStream fis = new FileInputStream(tmpFile)) {
+        prep.setObject(1, fis, Types.BLOB);
+        prep.execute();
+      }
+      try (FileInputStream fis = new FileInputStream(tmpFile)) {
+        prep.setObject(1, fis, Types.BLOB, 5000);
+        prep.execute();
+      }
+      try (FileInputStream fis = new FileInputStream(tmpFile)) {
+        try (FileInputStream fis2 = new FileInputStream(tmpFile)) {
+          prep.setObject(1, fis, Types.BLOB);
+          prep.addBatch();
+          prep.setObject(1, fis2, Types.BLOB, 5000);
+          prep.addBatch();
+          prep.executeBatch();
+        }
+      }
+      try (FileInputStream fis = new FileInputStream(tmpFile)) {
+        prep.setBlob(1, new BlobInputStream(fis));
+        prep.addBatch();
+        prep.executeBatch();
+      }
+      try (FileInputStream fis = new FileInputStream(tmpFile)) {
+        prep.setObject(1, new BlobInputStream(fis), Types.BLOB, 5000);
+        prep.addBatch();
+        prep.executeBatch();
+      }
+
+      prep.setObject(1, "e🌟6''".getBytes(StandardCharsets.UTF_8));
+      prep.addBatch();
+      prep.setObject(1, "e🌟76".getBytes(StandardCharsets.UTF_8), Types.BLOB, 6);
+      prep.addBatch();
+      prep.executeBatch();
+      prep.setObject(1, "e🌟85".getBytes(StandardCharsets.UTF_8), Types.BLOB, 6);
+      prep.execute();
+      prep.setBytes(1, "e🌟9''\\n".getBytes(StandardCharsets.UTF_8));
+      prep.execute();
+      prep.setBinaryStream(1, new ByteArrayInputStream("e🌟9".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setBinaryStream(
+          1, new ByteArrayInputStream("e🌟123".getBytes(StandardCharsets.UTF_8)), 6);
+      prep.execute();
+      prep.setBinaryStream(
+          1, new ByteArrayInputStream("e🌟456".getBytes(StandardCharsets.UTF_8)), 6L);
+      prep.execute();
+      prep.setBinaryStream(1, new ByteArrayInputStream("e🌟9".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setBinaryStream(
+          1, new ByteArrayInputStream("e🌟123".getBytes(StandardCharsets.UTF_8)), 6);
+      prep.execute();
+      prep.setBinaryStream(
+          1, new ByteArrayInputStream("e🌟456".getBytes(StandardCharsets.UTF_8)), 6L);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM BlobCodec2");
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟1".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getBlob(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+    rs.updateBlob(2, new MariaDbBlob("g🌟1".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertArrayEquals(
+        "g🌟1".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+    rs.updateBlob("t1", new MariaDbBlob("f🌟1".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertArrayEquals(
+        "f🌟1".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟2".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    rs.updateNull("t1");
+    rs.updateRow();
+    assertNull(rs.getBlob(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    rs.updateObject(2, new MariaDbBlob("f🌟2".getBytes(StandardCharsets.UTF_8)), 5);
+    rs.updateRow();
+    assertArrayEquals(
+        "f🌟".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟3".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟4".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟5".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(fileContent, rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        Arrays.copyOfRange(fileContent, 0, 5000),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(fileContent, rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        Arrays.copyOfRange(fileContent, 0, 5000),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(fileContent, rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        Arrays.copyOfRange(fileContent, 0, 5000),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟6''".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟7".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟8".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBytes("t1", "2g🌟12".getBytes(StandardCharsets.UTF_8));
+    rs.updateRow();
+    assertArrayEquals(
+        "2g🌟12".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟9''\\n".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBytes(2, "2g🌟15".getBytes(StandardCharsets.UTF_8));
+    rs.updateRow();
+    assertArrayEquals(
+        "2g🌟15".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟9".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBinaryStream(
+        "t1", new ByteArrayInputStream("2g🌟15".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertArrayEquals("2g🌟15".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟1".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBinaryStream(
+        "t1", new ByteArrayInputStream("2g🌟15".getBytes(StandardCharsets.UTF_8)), 7);
+    rs.updateRow();
+    assertArrayEquals("2g🌟1".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟4".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBinaryStream(
+        "t1", new ByteArrayInputStream("2g🌟456".getBytes(StandardCharsets.UTF_8)), 7L);
+    rs.updateRow();
+    assertArrayEquals("2g🌟4".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟9".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBinaryStream(2, new ByteArrayInputStream("2g🌟15".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertArrayEquals("2g🌟15".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟1".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBinaryStream(
+        2, new ByteArrayInputStream("2g🌟15".getBytes(StandardCharsets.UTF_8)), 7);
+    rs.updateRow();
+    assertArrayEquals("2g🌟1".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟4".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    rs.updateBinaryStream(
+        2, new ByteArrayInputStream("2g🌟456".getBytes(StandardCharsets.UTF_8)), 7L);
+    rs.updateRow();
+    assertArrayEquals("2g🌟4".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    rs = stmt.executeQuery("SELECT * FROM BlobCodec2");
+    assertTrue(rs.next());
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "g🌟1".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "f🌟1".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "f🌟".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟3".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertNull(rs.getBlob(2));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟4".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟5".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(fileContent, rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        Arrays.copyOfRange(fileContent, 0, 5000),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(fileContent, rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        Arrays.copyOfRange(fileContent, 0, 5000),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(fileContent, rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        Arrays.copyOfRange(fileContent, 0, 5000),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "e🌟6''".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟7".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "2g🌟12".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+    assertTrue(rs.next());
+    assertArrayEquals(
+        "2g🌟15".getBytes(StandardCharsets.UTF_8),
+        rs.getBlob(2).getBytes(1, (int) rs.getBlob(2).length()));
+
+    assertTrue(rs.next());
+    assertArrayEquals("2g🌟15".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("2g🌟1".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("2g🌟4".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("2g🌟15".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("2g🌟1".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+
+    assertTrue(rs.next());
+    assertArrayEquals("2g🌟4".getBytes(StandardCharsets.UTF_8), rs.getBytes(2));
+    con.commit();
+  }
+
+  private static class BlobInputStream implements Blob {
+    private final InputStream data;
+
+    public BlobInputStream(InputStream data) {
+      this.data = data;
+    }
+
+    @Override
+    public long length() throws SQLException {
+      throw new SQLException("Length not available");
+    }
+
+    @Override
+    public byte[] getBytes(final long pos, final int length) throws SQLException {
+
+      // if not have thrown an error
+      byte[] buf = new byte[length];
+      int len;
+      int intpos = 0;
+      try {
+        while ((len = data.read(buf, intpos, length - intpos)) > 0) {
+          intpos += len;
+          if (pos >= len) break;
+        }
+        return buf;
+      } catch (IOException io) {
+        throw new SQLException("Error reading stream");
+      }
+    }
+
+    @Override
+    public InputStream getBinaryStream() {
+      return data;
+    }
+
+    @Override
+    public long position(byte[] bytes, long l) {
+      return 0;
+    }
+
+    @Override
+    public long position(Blob blob, long l) {
+      return 0;
+    }
+
+    @Override
+    public int setBytes(long l, byte[] bytes) {
+      return 0;
+    }
+
+    @Override
+    public int setBytes(long l, byte[] bytes, int i, int i1) {
+      return 0;
+    }
+
+    @Override
+    public OutputStream setBinaryStream(long l) {
+      return null;
+    }
+
+    @Override
+    public void truncate(long l) {}
+
+    @Override
+    public void free() {}
+
+    @Override
+    public InputStream getBinaryStream(long l, long l1) {
+      return null;
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/CharCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/CharCodecTest.java
new file mode 100644
index 0000000..b2290b9
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/CharCodecTest.java
@@ -0,0 +1,732 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class CharCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS CharCodec");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE CharCodec (t1 CHAR(30), t2 CHAR(30), t3 CHAR(25), t4 CHAR(25)) CHARACTER "
+            + "SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+    stmt.execute(
+        "INSERT INTO CharCodec VALUES ('0', '1', 'some🌟', null), ('2011-01-01', '2010-12-31"
+            + " 23:59:59.152', '23:54:51.840010', null),('2010-12-31T23:59:59.152+01:00',"
+            + " '2010-12-31T23:59:59.152Z', null, null)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from CharCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from CharCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getObject(2));
+    assertEquals("1", rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testArrObject(rs, new byte[] {(byte) '0'});
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testObject(rs, Clob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, NClob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, InputStream.class, new MariaDbClob("0".getBytes()).getBinaryStream());
+    testObject(rs, Reader.class, new StringReader("0"));
+    rs.next();
+    testObject(rs, LocalDate.class, LocalDate.parse("2011-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2011-01-01T00:00"));
+    testObject(rs, LocalTime.class, LocalTime.parse("23:54:51.840010"), 3);
+    Time t = Time.valueOf("23:54:51");
+    testObject(rs, Time.class, new Time(t.getTime() + 840), 3);
+    testObject(rs, Date.class, Date.valueOf("2011-01-01"));
+    Timestamp tt = Timestamp.valueOf("2010-12-31 23:59:59");
+    testObject(rs, Timestamp.class, new Timestamp(tt.getTime() + 152), 2);
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2011-01-01T00:00").atZone(ZoneId.systemDefault()));
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-12-31"), 2);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getByte(3), " cannot be decoded as Byte");
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getShort(3), "value 'some🌟' cannot be decoded as Short");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(3), "value 'some🌟' cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getLong(3),
+        "value 'some\uD83C\uDF1F' cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(3), "value 'some🌟' cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(3),
+        "value 'some🌟' cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(3),
+        "value 'some🌟' cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), " cannot be decoded as Date");
+    rs.next();
+    assertEquals("2011-01-01", rs.getDate(1).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate(2).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate("t2alias").toString());
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(3), " cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "value '2011-01-01' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(2),
+        "value '2010-12-31 23:59:59.152' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(3).getTime());
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    rs.next();
+    assertEquals(Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152, rs.getTimestamp(2).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152,
+        rs.getTimestamp("t2alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t2alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    assertTrue(rs.next());
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "cannot be decoded as OffsetDateTime");
+    assertTrue(rs.next());
+    assertEquals(
+        OffsetDateTime.parse("2010-12-31T23:59:59.152+01:00"),
+        rs.getObject(1, OffsetDateTime.class));
+    assertEquals(
+        OffsetDateTime.parse("2010-12-31T23:59:59.152Z"), rs.getObject(2, OffsetDateTime.class));
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getAsciiStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getAsciiStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getAsciiStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getUnicodeStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)),
+        rs.getUnicodeStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getUnicodeStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getBinaryStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBinaryStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBinaryStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws Exception {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws Exception {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) throws Exception {
+    assertArrayEquals("0".getBytes(), rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(), rs.getBytes(2));
+    assertArrayEquals("1".getBytes(), rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBytes(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getNCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getNCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getBlob(1), "(not binary) cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getNClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getNClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+
+    assertTrue(
+        "CHAR".equals(meta.getColumnTypeName(1)) || "VARCHAR".equals(meta.getColumnTypeName(1)));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.String", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertTrue(Types.CHAR == meta.getColumnType(1) || Types.VARCHAR == meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    if (!isXpand()) {
+      assertEquals(30, meta.getColumnDisplaySize(1));
+      assertEquals(30, meta.getPrecision(1));
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/ClobCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/ClobCodecTest.java
new file mode 100644
index 0000000..ccdafd4
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/ClobCodecTest.java
@@ -0,0 +1,1014 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class ClobCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS ClobCodec");
+    stmt.execute("DROP TABLE IF EXISTS ClobParamCodec");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE ClobCodec (t1 TINYTEXT, t2 TEXT, t3 MEDIUMTEXT, t4 LONGTEXT) CHARACTER "
+            + "SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+    stmt.execute(
+        "INSERT INTO ClobCodec VALUES ('0', '1', 'some🌟', null), ('2011-01-01', '2010-12-31"
+            + " 23:59:59.152', '23:54:51.840010', null)");
+    stmt.execute(
+        "CREATE TABLE ClobParamCodec(id int not null primary key auto_increment, t1 TEXT) "
+            + "CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from ClobCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from ClobCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals(new MariaDbClob("0".getBytes()), rs.getObject(1, Clob.class));
+    assertFalse(rs.wasNull());
+    assertEquals(new MariaDbClob("1".getBytes()), rs.getObject(2, Clob.class));
+    assertEquals(new MariaDbClob("1".getBytes()), rs.getObject("t2alias", Clob.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getObject(3, Clob.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Byte.class, Byte.valueOf("0"));
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testArrObject(rs, new byte[] {(byte) '0'});
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testObject(rs, Clob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, NClob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, InputStream.class, new MariaDbClob("0".getBytes()).getBinaryStream());
+    testObject(rs, Reader.class, new StringReader("0"));
+    rs.next();
+    testObject(rs, LocalDate.class, LocalDate.parse("2011-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2011-01-01T00:00"));
+    testObject(rs, LocalTime.class, LocalTime.parse("23:54:51.840010"), 3);
+    Time t = Time.valueOf("23:54:51");
+    testObject(rs, Time.class, new Time(t.getTime() + 840), 3);
+    testObject(rs, Date.class, Date.valueOf("2011-01-01"));
+    Timestamp tt = Timestamp.valueOf("2010-12-31 23:59:59");
+    testObject(rs, Timestamp.class, new Timestamp(tt.getTime() + 152), 2);
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2011-01-01T00:00").atZone(ZoneId.systemDefault()));
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-12-31"), 2);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getByte(3),
+        "value 'some\uD83C\uDF1F' (BLOB) cannot be decoded as Byte");
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getShort(3), "value 'some🌟' cannot be decoded as Short");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(3), "value 'some🌟' cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getLong(3),
+        "value 'some\uD83C\uDF1F' cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(3), "value 'some🌟' cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(3),
+        "value 'some🌟' cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(3),
+        "value 'some🌟' cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "value '0' (BLOB) cannot be decoded as Date");
+    rs.next();
+    assertEquals("2011-01-01", rs.getDate(1).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate(2).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate("t2alias").toString());
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(3),
+        "value '23:54:51.840010' (BLOB) cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "BLOB value '2011-01-01' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(2),
+        "BLOB value '2010-12-31 23:59:59.152' cannot be decoded as Time");
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(3).getTime());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime("t3alias").getTime());
+    Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+    assertEquals(86091840, rs.getTime(3, utc).getTime());
+    assertEquals(86091840, rs.getTime("t3alias", utc).getTime());
+
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    rs.next();
+
+    assertEquals(Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152, rs.getTimestamp(2).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152,
+        rs.getTimestamp("t2alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t2alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    //
+    //    ('2011-01-01', '2010-12-31 23:59:59.152',"
+    //            + " '23:54:51.840010', null)
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "cannot be decoded as OffsetDateTime");
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getAsciiStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getAsciiStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getAsciiStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getUnicodeStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)),
+        rs.getUnicodeStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getUnicodeStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getBinaryStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBinaryStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBinaryStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) throws SQLException {
+    assertArrayEquals("0".getBytes(), rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(), rs.getBytes(2));
+    assertArrayEquals("1".getBytes(), rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBytes(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getNCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getNCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBlob(1),
+        "Data type BLOB (not binary) cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getNClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getNClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("VARCHAR", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.String", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARCHAR, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    if (!isXpand()) {
+      assertEquals(255, meta.getColumnDisplaySize(1));
+      assertEquals(255, meta.getPrecision(1));
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+    String urlWithHaMode =
+        mDefUrl.replaceAll("jdbc:mariadb:", "jdbc:mariadb:sequential:")
+            + (mDefUrl.indexOf("?") > 0 ? "&" : "?")
+            + "useServerPrepStmts=true";
+    try (Connection con = DriverManager.getConnection(urlWithHaMode)) {
+      sendParam(con);
+    }
+
+    try (Connection con = createCon("transactionReplay=true&useServerPrepStmts=false")) {
+      sendParam(con);
+    }
+    try (Connection con = createCon("transactionReplay=true&useServerPrepStmts=true")) {
+      sendParam(con);
+    }
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    StringBuilder longDataSb = new StringBuilder(20000);
+
+    for (int i = 0; i < 20000; i++) {
+      longDataSb.append('0' + i % 16);
+    }
+    Clob longData = new MariaDbClob(longDataSb.toString().getBytes(StandardCharsets.UTF_8));
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE ClobParamCodec");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO ClobParamCodec(t1) VALUES (?)")) {
+      prep.setClob(1, new MariaDbClob("e🌟£1".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setClob(1, (Clob) null);
+      prep.execute();
+      prep.setObject(1, "e🌟2");
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, "e🌟3", Types.VARCHAR);
+      prep.execute();
+      prep.setObject(1, null, Types.VARCHAR);
+      prep.execute();
+      prep.setObject(1, null, Types.VARCHAR);
+      prep.execute();
+      prep.setObject(1, new MariaDbClob("e🌟56".getBytes(StandardCharsets.UTF_8)), Types.CLOB, 4);
+      prep.execute();
+      prep.setObject(1, longData);
+
+      prep.setClob(1, new MariaDbClob("e🌟1".getBytes(StandardCharsets.UTF_8)));
+      prep.addBatch();
+      prep.setClob(1, new MariaDbClob("e🌟1".getBytes(StandardCharsets.UTF_8)));
+      prep.addBatch();
+      prep.setClob(1, longData);
+      prep.addBatch();
+      prep.setClob(1, (Clob) null);
+      prep.addBatch();
+      prep.setObject(1, new MariaDbClob("e🌟56".getBytes(StandardCharsets.UTF_8)), Types.CLOB, 4);
+      prep.addBatch();
+      prep.executeBatch();
+
+      prep.setCharacterStream(1, new StringReader("e🌟789"));
+      prep.execute();
+      prep.setCharacterStream(1, new StringReader("e🌟890"), 4);
+      prep.execute();
+      prep.setObject(1, new StringReader(longDataSb.toString()), Types.CLOB);
+      prep.execute();
+      prep.setObject(1, new StringReader("e🌟568"), Types.CLOB, 4);
+      prep.execute();
+
+      prep.setCharacterStream(1, new StringReader("e🌟789"));
+      prep.addBatch();
+      prep.setCharacterStream(1, new StringReader("e🌟890"), 4);
+      prep.addBatch();
+      prep.executeBatch();
+
+      prep.setNClob(1, new MariaDbClob("e🌟1".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+
+      prep.setNClob(1, new MariaDbClob("e🌟145".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+
+      prep.setNCharacterStream(1, new StringReader("e🌟789"));
+      prep.execute();
+      prep.setNCharacterStream(1, new StringReader("e🌟890"), 4);
+      prep.execute();
+      prep.setNCharacterStream(1, new StringReader("e🌟789"));
+      prep.execute();
+      prep.setNCharacterStream(1, new StringReader("e🌟890"), 4);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM ClobParamCodec");
+    assertTrue(rs.next());
+    assertEquals("e🌟£1", rs.getString(2));
+    rs.updateClob(2, new MariaDbClob("f🌟10".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("f🌟10", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateClob("t1", new MariaDbClob("f🌟15".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("f🌟15", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟2", rs.getString(2));
+    rs.updateClob("t1", (Clob) null);
+    rs.updateRow();
+    assertNull(rs.getString(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject("t1", new MariaDbClob("f🌟56".getBytes(StandardCharsets.UTF_8)), 4);
+    rs.updateRow();
+    assertEquals("f🌟5", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟3", rs.getString(2));
+    rs.updateCharacterStream(2, new StringReader("e🌟789"));
+    rs.updateRow();
+    assertEquals("e🌟789", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateCharacterStream(2, new StringReader("e🌟789"), 4);
+    rs.updateRow();
+    assertEquals("e🌟7", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateCharacterStream(2, new StringReader("e🌟789"), 4L);
+    rs.updateRow();
+    assertEquals("e🌟7", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟5", rs.getString(2));
+    rs.updateCharacterStream("t1", new StringReader("e🌟789"));
+    rs.updateRow();
+    assertEquals("e🌟789", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟1", rs.getString(2));
+    rs.updateCharacterStream("t1", new StringReader("e🌟789"), 4);
+    rs.updateRow();
+    assertEquals("e🌟7", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟1", rs.getString(2));
+    rs.updateCharacterStream("t1", new StringReader("e🌟789"), 4L);
+    rs.updateRow();
+    assertEquals("e🌟7", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals(longDataSb.toString(), rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟5", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟8", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(longDataSb.toString(), rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟5", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟8", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟1", rs.getString(2));
+    rs.updateNClob(2, new MariaDbClob("g🌟14".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("g🌟14", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟145", rs.getString(2));
+    rs.updateNClob("t1", new MariaDbClob("h🌟14".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("h🌟14", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    rs.updateNCharacterStream("t1", new StringReader("e🌟5789"));
+    rs.updateRow();
+    assertEquals("e🌟5789", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟8", rs.getString(2));
+    rs.updateNCharacterStream("t1", new StringReader("e🌟5789"), 5);
+    rs.updateRow();
+    assertEquals("e🌟57", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    rs.updateNCharacterStream(2, new StringReader("e🌟5789"));
+    rs.updateRow();
+    assertEquals("e🌟5789", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟8", rs.getString(2));
+    rs.updateNCharacterStream(2, new StringReader("e🌟5789"), 5);
+    rs.updateRow();
+    assertEquals("e🌟57", rs.getString(2));
+
+    rs = stmt.executeQuery("SELECT * FROM ClobParamCodec");
+    assertTrue(rs.next());
+    assertEquals("f🌟10", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("f🌟15", rs.getString(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.wasNull());
+    assertTrue(rs.next());
+    assertEquals("f🌟5", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟7", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟7", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟7", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟7", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(longDataSb.toString(), rs.getString(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟5", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟8", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(longDataSb.toString(), rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟5", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟8", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("g🌟14", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("h🌟14", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟5789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟57", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟5789", rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("e🌟57", rs.getString(2));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/CommonCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/CommonCodecTest.java
new file mode 100644
index 0000000..99bcad2
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/CommonCodecTest.java
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.*;
+import org.junit.jupiter.api.Assertions;
+import org.mariadb.jdbc.integration.Common;
+
+public class CommonCodecTest extends Common {
+
+  void assertReaderEquals(Reader expected, Reader result) throws IOException {
+    int res1 = 0;
+    int res2 = 0;
+    while (res1 != -1 && res2 != -1) {
+      res1 = expected.read();
+      res2 = result.read();
+      Assertions.assertEquals(res1, res2);
+    }
+  }
+
+  void assertStreamEquals(InputStream expected, InputStream result) throws IOException {
+    int res1 = 0;
+    int res2 = 0;
+    while (res1 != -1 && res2 != -1) {
+      res1 = expected.read();
+      res2 = result.read();
+      Assertions.assertEquals(res1, res2);
+    }
+  }
+
+  void assertStreamEquals(Blob expected, Blob result) throws Exception {
+    assertStreamEquals(expected.getBinaryStream(), result.getBinaryStream());
+  }
+
+  void assertStreamEquals(Clob expected, Clob result) throws Exception {
+    assertReaderEquals(expected.getCharacterStream(), result.getCharacterStream());
+  }
+
+  void testObject(ResultSet rs, Class<?> objClass, Object exp) throws Exception {
+    testObject(rs, objClass, exp, 1);
+  }
+
+  void testObject(ResultSet rs, Class<?> objClass, Object exp, int idx) throws Exception {
+    if (exp instanceof Blob) {
+      assertStreamEquals((Blob) exp, (Blob) rs.getObject(idx, objClass));
+      assertStreamEquals((Blob) exp, (Blob) rs.getObject("t" + idx + "alias", objClass));
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    } else if (exp instanceof Clob) {
+      assertStreamEquals((Clob) exp, (Clob) rs.getObject(idx, objClass));
+      assertStreamEquals((Clob) exp, (Clob) rs.getObject("t" + idx + "alias", objClass));
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    } else if (exp instanceof InputStream) {
+      assertStreamEquals((InputStream) exp, (InputStream) rs.getObject(idx, objClass));
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    } else if (exp instanceof byte[]) {
+      assertArrayEquals((byte[]) exp, (byte[]) rs.getObject(idx, objClass));
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    } else if (exp instanceof Reader) {
+      assertReaderEquals((Reader) exp, (Reader) rs.getObject(idx, objClass));
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    } else if (exp instanceof Time) {
+      assertEquals(((Time) exp).getTime(), ((Time) rs.getObject(idx, objClass)).getTime());
+      assertEquals(
+          ((Time) exp).getTime(), ((Time) rs.getObject("t" + idx + "alias", objClass)).getTime());
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    } else if (exp instanceof Date) {
+      assertEquals(((Date) exp).getTime(), ((Date) rs.getObject(idx, objClass)).getTime());
+      assertEquals(
+          ((Date) exp).getTime(), ((Date) rs.getObject("t" + idx + "alias", objClass)).getTime());
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    } else {
+      assertEquals(exp, rs.getObject(idx, objClass));
+      assertEquals(exp, rs.getObject("t" + idx + "alias", objClass));
+      assertNull(rs.getObject(4, objClass));
+      assertNull(rs.getObject("t4alias", objClass));
+    }
+  }
+
+  void testErrObject(ResultSet rs, Class<?> objClass, int index) throws SQLException {
+    Assertions.assertThrows(SQLException.class, () -> rs.getObject(index, objClass));
+    Assertions.assertThrows(
+        SQLException.class, () -> rs.getObject("t" + index + "alias", objClass));
+  }
+
+  void testErrObject(ResultSet rs, Class<?> objClass) throws SQLException {
+    testErrObject(rs, objClass, 1);
+    assertNull(rs.getObject(4, objClass));
+    assertNull(rs.getObject("t4alias", objClass));
+  }
+
+  void testArrObject(ResultSet rs, byte[] exp, int index) throws SQLException {
+    assertArrayEquals(exp, (byte[]) rs.getObject(index, (Class<?>) byte[].class));
+    assertArrayEquals(exp, (byte[]) rs.getObject("t" + index + "alias", (Class<?>) byte[].class));
+  }
+
+  void testArrObject(ResultSet rs, byte[] exp) throws SQLException {
+    testArrObject(rs, exp, 1);
+    assertNull(rs.getObject(4, (Class<?>) byte[].class));
+    assertNull(rs.getObject("t4alias", (Class<?>) byte[].class));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/DateCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/DateCodecTest.java
new file mode 100644
index 0000000..cc919c1
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/DateCodecTest.java
@@ -0,0 +1,810 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class DateCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS DateCodec");
+    stmt.execute("DROP TABLE IF EXISTS DateCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE DateCodec (t1 DATE, t2 DATE, t3 DATE, t4 DATE)");
+    stmt.execute(
+        "INSERT INTO DateCodec VALUES ('2010-01-12', '1000-01-01', '9999-12-31', null)"
+            + (isMariaDBServer() ? ",('0000-00-00', '1000-01-01', '9999-12-31', null)" : ""));
+    stmt.execute("CREATE TABLE DateCodec2 (id int not null primary key auto_increment, t1 DATE)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DateCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DateCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("2010-01-12").getTime(), ((Date) rs.getObject(1)).getTime());
+    assertFalse(rs.wasNull());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("1000-01-01").getTime(), ((Date) rs.getObject(2)).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("9999-12-31").getTime(), ((Date) rs.getObject(3)).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testObject(rs, String.class, "2010-01-12");
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Duration.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testObject(rs, LocalDate.class, LocalDate.parse("2010-01-12"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2010-01-12T00:00:00"));
+    testErrObject(rs, LocalTime.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, BigInteger.class);
+    testObject(rs, Timestamp.class, Timestamp.valueOf("2010-01-12 00:00:00"));
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2010-01-12T00:00:00").atZone(ZoneId.systemDefault()));
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-01-12"));
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("2010-01-12", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1000-01-01", rs.getString(2));
+    assertEquals("1000-01-01", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("9999-12-31", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertTrue("0000-00-00".equals(rs.getString(1)));
+    }
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("2010-01-12", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1000-01-01", rs.getNString(2));
+    assertEquals("1000-01-01", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("9999-12-31", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBoolean(1), "Data type DATE cannot be decoded as Boolean");
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getByte(1), "Data type DATE cannot be decoded as Byte");
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getShort(1), "Data type DATE cannot be decoded as Short");
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getInt(1), "Data type DATE cannot be decoded as Integer");
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getLong(1), "Data type DATE cannot be decoded as Long");
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getFloat(1), "Data type DATE cannot be decoded as Float");
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getDouble(1), "Data type DATE cannot be decoded as Double");
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBigDecimal(1),
+        "Data type DATE cannot be decoded as BigDecimal");
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    assertEquals(
+        1263254400000L, rs.getDate(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("2010-01-12").getTime(), rs.getDate(1).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        -30609792000000L,
+        rs.getDate(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        -30609792000000L,
+        rs.getDate("t2alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("1000-01-01").getTime(), rs.getDate(2).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("9999-12-31").getTime(), rs.getDate(3).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getDate(1));
+    }
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getTime(1), "Data type DATE cannot be decoded as Time");
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(get());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPrepare(sharedConn));
+    getDuration(getPrepare(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, Duration.class),
+        "Type class java.time.Duration not supported type for DATE type");
+  }
+
+  @Test
+  public void getLocalTime() throws SQLException {
+    getLocalTime(get());
+  }
+
+  @Test
+  public void getLocalTimePrepare() throws SQLException {
+    getLocalTime(getPrepare(sharedConn));
+    getLocalTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, LocalTime.class),
+        "Type class java.time.LocalTime not supported type for DATE type");
+  }
+
+  @Test
+  public void getLocalDate() throws SQLException {
+    getLocalDate(get());
+  }
+
+  @Test
+  public void getLocalDatePrepare() throws SQLException {
+    getLocalDate(getPrepare(sharedConn));
+    getLocalDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDate(ResultSet rs) throws SQLException {
+    assertEquals(LocalDate.parse("2010-01-12"), rs.getObject(1, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDate.parse("1000-01-01"), rs.getObject(2, LocalDate.class));
+    assertEquals(LocalDate.parse("1000-01-01"), rs.getObject("t2alias", LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDate.parse("9999-12-31"), rs.getObject(3, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, LocalDate.class));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getObject(1, LocalDate.class));
+    }
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    assertEquals(Timestamp.valueOf("2010-01-12 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        1263254400000L,
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-01-12 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        1263254400000L,
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Timestamp.valueOf("1000-01-01 00:00:00").getTime(), rs.getTimestamp(2).getTime());
+    assertEquals(
+        -30609792000000L,
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(Timestamp.valueOf("9999-12-31 00:00:00").getTime(), rs.getTimestamp(3).getTime());
+    assertEquals(
+        253402214400000L,
+        rs.getTimestamp(3, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Timestamp.valueOf("9999-12-31 00:00:00"), rs.getTimestamp(3));
+    assertNull(rs.getTimestamp(4));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getTimestamp(1));
+    }
+  }
+
+  @Test
+  public void getLocalDateTime() throws SQLException {
+    getLocalDateTime(get());
+  }
+
+  @Test
+  public void getLocalDateTimePrepare() throws SQLException {
+    getLocalDateTime(getPrepare(sharedConn));
+    getLocalDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDateTime(ResultSet rs) throws SQLException {
+    assertEquals(LocalDateTime.parse("2010-01-12T00:00:00"), rs.getObject(1, LocalDateTime.class));
+    assertEquals(
+        LocalDateTime.parse("2010-01-12T00:00:00"), rs.getObject("t1alias", LocalDateTime.class));
+    assertNull(rs.getObject(4, LocalDateTime.class));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getObject(1, LocalDateTime.class));
+    }
+  }
+
+  @Test
+  public void getInstant() throws SQLException {
+    getInstant(get());
+  }
+
+  @Test
+  public void getInstantPrepare() throws SQLException {
+    getInstant(getPrepare(sharedConn));
+    getInstant(getPrepare(sharedConnBinary));
+  }
+
+  public void getInstant(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("2010-01-12T00:00:00"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(1, Instant.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("1000-01-01T00:00:00"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(2, Instant.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("9999-12-31T00:00:00"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(3, Instant.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, Instant.class));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "cannot be decoded as OffsetDateTime");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type DATE cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws SQLException {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type DATE cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws SQLException {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type DATE cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBytes(1), "Data type DATE cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws SQLException {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type DATE cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws SQLException {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type DATE cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBlob(1), "Data type DATE cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws SQLException {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getClob(1), "Data type DATE cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws SQLException {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getNClob(1), "Data type DATE cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("DATE", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.sql.Date", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.DATE, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(10, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(10, meta.getColumnDisplaySize(1));
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE DateCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO DateCodec2(t1) VALUES (?)")) {
+      prep.setDate(1, Date.valueOf("2010-01-12"));
+      prep.execute();
+      prep.setDate(1, null);
+      prep.execute();
+      prep.setObject(1, Date.valueOf("2010-01-13"));
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, Date.valueOf("2010-01-14"), Types.DATE);
+      prep.execute();
+      prep.setObject(1, null, Types.DATE);
+      prep.execute();
+      prep.setObject(1, LocalDate.parse("9999-12-31"), Types.DATE);
+      prep.execute();
+      prep.setDate(1, Date.valueOf("2010-01-12"), Calendar.getInstance());
+      prep.execute();
+      prep.setObject(1, new java.util.Date(Date.valueOf("2010-12-13").getTime()));
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM DateCodec2");
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-12"), rs.getDate(2));
+    rs.updateDate(2, Date.valueOf("2021-01-12"));
+    rs.updateRow();
+    assertEquals(Date.valueOf("2021-01-12"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateDate("t1", Date.valueOf("2021-01-15"));
+    rs.updateRow();
+    assertEquals(Date.valueOf("2021-01-15"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-13"), rs.getDate(2));
+    rs.updateDate(2, null);
+    rs.updateRow();
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject(2, Date.valueOf("2021-01-14"), Types.DATE);
+    rs.updateRow();
+    assertEquals(Date.valueOf("2021-01-14"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-14"), rs.getDate(2));
+    rs.updateObject(2, null, Types.DATE);
+    rs.updateRow();
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject(2, LocalDate.parse("9999-12-31"), Types.DATE);
+    rs.updateRow();
+    assertEquals(Date.valueOf("9999-12-31"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("9999-12-31"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-12"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-12-13"), rs.getDate(2));
+    rs.updateObject(2, new java.util.Date(Date.valueOf("2010-12-31").getTime()), Types.DATE);
+    rs.updateRow();
+
+    rs = stmt.executeQuery("SELECT * FROM DateCodec2");
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2021-01-12"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2021-01-15"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2021-01-14"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("9999-12-31"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("9999-12-31"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-12"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-12-31"), rs.getDate(2));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/DateTimeCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/DateTimeCodecTest.java
new file mode 100644
index 0000000..1106fdc
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/DateTimeCodecTest.java
@@ -0,0 +1,1274 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class DateTimeCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS DateTimeCodec");
+    stmt.execute("DROP TABLE IF EXISTS DateTimeCodec2");
+    stmt.execute("DROP TABLE IF EXISTS DateTimeCodec3");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE DateTimeCodec (t1 DATETIME , t2 DATETIME(6), t3 DATETIME(6), t4"
+            + " DATETIME(6))");
+    stmt.execute(
+        "INSERT INTO DateTimeCodec VALUES ('2010-01-12 01:55:12', '1000-01-01 01:55:13.212345',"
+            + " '9999-12-31 18:30:12.55', null)"
+            + (isMariaDBServer()
+                ? ",('0000-00-00 00:00:00', '0000-00-00 00:00:00', '9999-12-31 00:00:00.00', null)"
+                : ""));
+    stmt.execute(
+        "CREATE TABLE DateTimeCodec2 (id int not null primary key auto_increment, t1 DATETIME(6))");
+    stmt.execute(
+        "CREATE TABLE DateTimeCodec3 (id int not null primary key auto_increment, t1 DATETIME(6))");
+
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DateTimeCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement prepStmt =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DateTimeCodec"
+                + " WHERE 1 > ?");
+    prepStmt.closeOnCompletion();
+    prepStmt.setInt(1, 0);
+    ResultSet rs = prepStmt.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(
+        Timestamp.valueOf("2010-01-12 01:55:12").getTime(),
+        ((Timestamp) rs.getObject(1)).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        Timestamp.valueOf("1000-01-01 01:55:13.212345").getTime(),
+        ((Timestamp) rs.getObject(2)).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        Timestamp.valueOf("9999-12-31 18:30:12.55").getTime(),
+        ((Timestamp) rs.getObject(3)).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testObject(rs, String.class, "2010-01-12 01:55:12");
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testObject(rs, LocalDate.class, LocalDate.parse("2010-01-12"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2010-01-12T01:55:12"));
+    // get OffsetDateTime for "2010-01-12T01:55:12" corresponding with current zone id:
+    OffsetDateTime expOffsetDateTime =
+        OffsetDateTime.ofInstant(
+            Timestamp.valueOf("2010-01-12 01:55:12").toInstant(), ZoneId.systemDefault());
+    testObject(rs, OffsetDateTime.class, expOffsetDateTime);
+    testObject(
+        rs,
+        Instant.class,
+        ZonedDateTime.of(LocalDateTime.parse("2010-01-12T01:55:12"), ZoneId.systemDefault())
+            .toInstant());
+    testObject(rs, LocalTime.class, LocalTime.parse("01:55:12"));
+    testObject(rs, Time.class, Time.valueOf("01:55:12"));
+    testObject(rs, Timestamp.class, Timestamp.valueOf("2010-01-12 01:55:12"));
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2010-01-12T01:55:12").atZone(ZoneId.systemDefault()));
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-01-12"));
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get(), true);
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn), true);
+    getString(getPrepare(sharedConnBinary), false);
+  }
+
+  public void getString(ResultSet rs, boolean text) throws SQLException {
+    assertEquals("2010-01-12 01:55:12", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1000-01-01 01:55:13.212345", rs.getString(2));
+    assertEquals("1000-01-01 01:55:13.212345", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("9999-12-31 18:30:12.550000", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertEquals("0000-00-00 00:00:00", rs.getString(1));
+      if (isXpand() && !text) {
+        // https://jira.mariadb.org/browse/XPT-273
+        assertEquals("0000-00-00 00:00:00", rs.getString(2));
+        assertEquals("9999-12-31 00:00:00", rs.getString(3));
+      } else {
+        assertEquals("0000-00-00 00:00:00.000000", rs.getString(2));
+        assertEquals("9999-12-31 00:00:00.000000", rs.getString(3));
+      }
+    }
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("2010-01-12 01:55:12", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    String s = rs.getNString(2);
+    assertTrue(s.equals("1000-01-01 01:55:13.212345"));
+    s = rs.getNString("t2alias");
+    assertTrue(s.equals("1000-01-01 01:55:13.212345"));
+    assertFalse(rs.wasNull());
+    s = rs.getNString(3);
+    assertTrue(s.equals("9999-12-31 18:30:12.550000") || s.equals("9999-12-31 18:30:12.550"));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBoolean(1),
+        "Data type DATETIME cannot be decoded as Boolean");
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getByte(1), "Data type DATETIME cannot be decoded as Byte");
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getShort(1), "Data type DATETIME cannot be decoded as Short");
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getInt(1), "Data type DATETIME cannot be decoded as Integer");
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getLong(1), "Data type DATETIME cannot be decoded as Long");
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getFloat(1), "Data type DATETIME cannot be decoded as Float");
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getDouble(1),
+        "Data type DATETIME cannot be decoded as Double");
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBigDecimal(1),
+        "Data type DATETIME cannot be decoded as BigDecimal");
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    assertEquals(
+        1263254400000L
+            - TimeZone.getDefault().getOffset(Timestamp.valueOf("2010-01-12 01:55:12").getTime()),
+        rs.getDate(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        1263254400000L
+            - TimeZone.getDefault()
+                .getOffset(Timestamp.valueOf("2010-01-12 01:55:12.123456").getTime()),
+        rs.getDate(1).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        -30609792000000L
+            - TimeZone.getDefault().getOffset(Timestamp.valueOf("1000-01-01 01:55:13").getTime()),
+        rs.getDate(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        -30609792000000L
+            - TimeZone.getDefault().getOffset(Timestamp.valueOf("1000-01-01 01:55:13").getTime()),
+        rs.getDate(2).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        253402214400000L
+            - TimeZone.getDefault().getOffset(Timestamp.valueOf("9999-12-31 18:30:12").getTime()),
+        rs.getDate(3).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getTime(1));
+      assertNull(rs.getTime(2));
+    }
+  }
+
+  @Test
+  public void getDateTimezoneTest() throws SQLException {
+    TimeZone initialTz = Calendar.getInstance().getTimeZone();
+
+    TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
+    try (Connection conGmt8 = createCon("timezone=auto")) {
+      getDateTimezoneTestGmt8(conGmt8, getPrepare(conGmt8), TimeZone.getTimeZone("GMT+8"));
+      TimeZone.setDefault(TimeZone.getTimeZone("GMT-8"));
+      try (Connection conGmtm8 = createCon("timezone=auto")) {
+        getDateTimezoneTestGmtm8(conGmtm8, getPrepare(conGmtm8), TimeZone.getTimeZone("GMT-8"));
+      }
+      TimeZone.setDefault(initialTz);
+      try (Connection conAuto = createCon("timezone=auto")) {
+        getDateTimezoneTestNormal(conAuto, getPrepare(conAuto));
+      }
+
+    } finally {
+      TimeZone.setDefault(initialTz);
+    }
+  }
+
+  public void getDateTimezoneTestGmt8(Connection conGmt8, ResultSet rs, TimeZone tz)
+      throws SQLException {
+
+    assertEquals("2010-01-12T01:55:12+08:00", rs.getObject(1, OffsetDateTime.class).toString());
+
+    conGmt8.createStatement().execute("TRUNCATE TABLE DateTimeCodec3");
+    try (PreparedStatement prep =
+        conGmt8.prepareStatement("INSERT INTO DateTimeCodec3 values (?,?)")) {
+      prep.setInt(1, -2);
+      prep.setString(2, "2010-01-12 01:55:12");
+      prep.execute();
+
+      prep.setInt(1, 1);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12+08:00"));
+      prep.execute();
+
+      prep.setInt(1, 2);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12+01:00"));
+      prep.execute();
+
+      prep.setInt(1, 3);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12Z"));
+      prep.execute();
+
+      prep.setInt(1, 4);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T17:55:12-04:00"));
+      prep.execute();
+    }
+    conGmt8.commit();
+
+    java.sql.Statement stmt = conGmt8.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prepStmt = conGmt8.prepareStatement("select * from DateTimeCodec3")) {
+      rs = prepStmt.executeQuery();
+      rs.next();
+      assertEquals("2010-01-12T01:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));
+
+      rs.next();
+      assertEquals("2010-01-12T01:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-12 01:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263232512000L, rs.getTimestamp(2).getTime());
+      assertEquals(
+          "2010-01-12 09:55:12.0",
+          rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
+      assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-12", rs.getDate(2).toString());
+      assertEquals(
+          "2010-01-12",
+          rs.getDate(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
+      assertEquals("2010-01-12T01:55:12", rs.getObject(2, LocalDateTime.class).toString());
+
+      rs.next();
+      assertEquals("2010-01-12T08:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-12 08:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263257712000L, rs.getTimestamp(2).getTime());
+      assertEquals("2010-01-12 08:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-12", rs.getDate(2).toString());
+
+      rs.next();
+      assertEquals("2010-01-12T09:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-12 09:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263261312000L, rs.getTimestamp(2).getTime());
+      assertEquals("2010-01-12 09:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-12", rs.getDate(2).toString());
+
+      rs.next();
+      assertEquals("2010-01-13T05:55:12+08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-13 05:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263333312000L, rs.getTimestamp(2).getTime());
+      assertEquals("2010-01-13 05:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-13", rs.getDate(2).toString());
+    }
+    conGmt8.rollback();
+  }
+
+  public void getDateTimezoneTestGmtm8(Connection conGmt8, ResultSet rs, TimeZone tz)
+      throws SQLException {
+
+    assertEquals("2010-01-12T01:55:12-08:00", rs.getObject(1, OffsetDateTime.class).toString());
+
+    conGmt8.createStatement().execute("TRUNCATE TABLE DateTimeCodec3");
+    try (PreparedStatement prep =
+        conGmt8.prepareStatement("INSERT INTO DateTimeCodec3 values (?,?)")) {
+      prep.setInt(1, -2);
+      prep.setString(2, "2010-01-12 01:55:12");
+      prep.execute();
+
+      prep.setInt(1, 1);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12-08:00"));
+      prep.execute();
+
+      prep.setInt(1, 2);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12-01:00"));
+      prep.execute();
+
+      prep.setInt(1, 3);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T01:55:12Z"));
+      prep.execute();
+
+      prep.setInt(1, 4);
+      prep.setObject(2, OffsetDateTime.parse("2010-01-12T17:55:12+04:00"));
+      prep.execute();
+    }
+    conGmt8.commit();
+
+    java.sql.Statement stmt = conGmt8.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prepStmt = conGmt8.prepareStatement("select * from DateTimeCodec3")) {
+      rs = prepStmt.executeQuery();
+      rs.next();
+      assertEquals("2010-01-12T01:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));
+
+      rs.next();
+      assertEquals("2010-01-12T01:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-12 01:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263290112000L, rs.getTimestamp(2).getTime());
+      assertEquals(
+          "2010-01-11 17:55:12.0",
+          rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
+      assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-12", rs.getDate(2).toString());
+      assertEquals(
+          "2010-01-11",
+          rs.getDate(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).toString());
+      assertEquals("2010-01-12T01:55:12", rs.getObject(2, LocalDateTime.class).toString());
+
+      rs.next();
+      assertEquals("2010-01-11T18:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-11 18:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263264912000L, rs.getTimestamp(2).getTime());
+      assertEquals("2010-01-11 18:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-11", rs.getDate(2).toString());
+
+      rs.next();
+      assertEquals("2010-01-11T17:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-11 17:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263261312000L, rs.getTimestamp(2).getTime());
+      assertEquals("2010-01-11 17:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-11", rs.getDate(2).toString());
+
+      rs.next();
+      assertEquals("2010-01-12T05:55:12-08:00", rs.getObject(2, OffsetDateTime.class).toString());
+      assertEquals("2010-01-12 05:55:12.0", rs.getTimestamp(2).toString());
+      assertEquals(1263304512000L, rs.getTimestamp(2).getTime());
+      assertEquals("2010-01-12 05:55:12.000000", rs.getString(2));
+      assertEquals("2010-01-12", rs.getDate(2).toString());
+    }
+    conGmt8.rollback();
+  }
+
+  public void getDateTimezoneTestNormal(Connection conAuto, ResultSet rs) throws SQLException {
+
+    assertEquals("2010-01-12 01:55:12.0", rs.getObject(1, Timestamp.class).toString());
+
+    conAuto.createStatement().execute("TRUNCATE TABLE DateTimeCodec3");
+    try (PreparedStatement prep =
+        conAuto.prepareStatement("INSERT INTO DateTimeCodec3 values (?,?)")) {
+      prep.setInt(1, 5);
+      prep.setString(2, "2010-01-12 01:55:12");
+      prep.execute();
+
+      prep.setInt(1, 6);
+      prep.setObject(2, "2010-01-12 11:55:12");
+      prep.execute();
+    }
+    conAuto.commit();
+
+    java.sql.Statement stmt = conAuto.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prepStmt =
+        conAuto.prepareStatement("select * from DateTimeCodec3 order by id")) {
+      rs = prepStmt.executeQuery();
+      rs.next();
+      assertEquals(5, rs.getInt(1));
+      assertEquals("2010-01-12T01:55:12", rs.getObject(2, LocalDateTime.class).toString());
+      assertEquals("2010-01-12 01:55:12.000000", rs.getString(2));
+
+      rs.next();
+
+      Timestamp tt = Timestamp.valueOf("2010-01-12 01:55:12");
+      int offset = TimeZone.getDefault().getOffset(tt.getTime());
+      int offsetHour = offset / (3_600_000);
+      if (offsetHour < 0) offsetHour = offsetHour * -1;
+
+      // test might fail if run in timezone with offset not rounded to hours
+      if (offsetHour == 0) {
+        assertEquals("2010-01-12T11:55:12Z", rs.getObject(2, OffsetDateTime.class).toString());
+      } else {
+        assertEquals(
+            "2010-01-12T11:55:12"
+                + ((offset < 0) ? "-" : "+")
+                + ((offsetHour < 10) ? "0" : offsetHour / 10)
+                + (offsetHour % 10)
+                + ":00",
+            rs.getObject(2, OffsetDateTime.class).toString());
+      }
+      assertEquals("2010-01-12 11:55:12.0", rs.getTimestamp(2).toString());
+    }
+    conAuto.rollback();
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    assertEquals(
+        6912000, rs.getTime(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(Time.valueOf("01:55:12").getTime(), rs.getTime(1).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        6913212, rs.getTime(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("01:55:13").getTime() + 212, rs.getTime(2).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("18:30:12").getTime() + 550, rs.getTime(3).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getTime(4));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getTime(1));
+    }
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(get());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPrepare(sharedConn));
+    getDuration(getPrepare(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) throws SQLException {
+    assertEquals(Duration.parse("PT265H55M12S"), rs.getObject(1, Duration.class));
+    assertEquals(Duration.parse("PT1H55M13.212345S"), rs.getObject(2, Duration.class));
+    assertNull(rs.getObject(4, Duration.class));
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getObject(1, Duration.class));
+    }
+  }
+
+  @Test
+  public void getLocalTime() throws SQLException {
+    getLocalTime(get());
+  }
+
+  @Test
+  public void getLocalTimePrepare() throws SQLException {
+    getLocalTime(getPrepare(sharedConn));
+    getLocalTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalTime(ResultSet rs) throws SQLException {
+    assertEquals(LocalTime.parse("01:55:12"), rs.getObject(1, LocalTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalTime.parse("01:55:13.212345"), rs.getObject(2, LocalTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalTime.parse("18:30:12.55"), rs.getObject(3, LocalTime.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, LocalTime.class));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getTime(1));
+    }
+  }
+
+  @Test
+  public void getLocalDate() throws SQLException {
+    getLocalDate(get());
+  }
+
+  @Test
+  public void getLocalDatePrepare() throws SQLException {
+    getLocalDate(getPrepare(sharedConn));
+    getLocalDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDate(ResultSet rs) throws SQLException {
+    assertEquals(LocalDate.parse("2010-01-12"), rs.getObject(1, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDate.parse("1000-01-01"), rs.getObject(2, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDate.parse("9999-12-31"), rs.getObject(3, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, LocalTime.class));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getObject(1, LocalDate.class));
+    }
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(Timestamp.valueOf("2010-01-12 01:55:12").getTime(), rs.getTimestamp(1).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        Timestamp.valueOf("1000-01-01 01:55:13.212345").getTime(), rs.getTimestamp(2).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(
+        Timestamp.valueOf("9999-12-31 18:30:12.55").getTime(), rs.getTimestamp(3).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getTimestamp(4));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getTimestamp(1));
+      assertNull(rs.getTimestamp(2));
+      assertEquals(
+          Timestamp.valueOf("9999-12-31 00:00:00.00").getTime(), rs.getTimestamp(3).getTime());
+    }
+  }
+
+  @Test
+  public void getLocalDateTime() throws SQLException {
+    getLocalDateTime(get());
+  }
+
+  @Test
+  public void getLocalDateTimePrepare() throws SQLException {
+    getLocalDateTime(getPrepare(sharedConn));
+    getLocalDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDateTime(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDateTime.parse("2010-01-12T01:55:12"), rs.getObject(1, LocalDateTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        LocalDateTime.parse("1000-01-01T01:55:13.212345"), rs.getObject(2, LocalDateTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        LocalDateTime.parse("9999-12-31T18:30:12.55"), rs.getObject(3, LocalDateTime.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, LocalDateTime.class));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getTimestamp(1));
+      assertNull(rs.getTimestamp(2));
+      assertEquals(
+          LocalDateTime.parse("9999-12-31T00:00:00.00"), rs.getObject(3, LocalDateTime.class));
+    }
+  }
+
+  @Test
+  public void getInstant() throws SQLException {
+    getInstant(get());
+  }
+
+  @Test
+  public void getInstantPrepare() throws SQLException {
+    getInstant(getPrepare(sharedConn));
+    getInstant(getPrepare(sharedConnBinary));
+  }
+
+  public void getInstant(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("2010-01-12T01:55:12"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(1, Instant.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("1000-01-01T01:55:13.212345"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(2, Instant.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("9999-12-31T18:30:12.55"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(3, Instant.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, Instant.class));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getTimestamp(1));
+      assertNull(rs.getTimestamp(2));
+      assertEquals(
+          ZonedDateTime.of(LocalDateTime.parse("9999-12-31T00:00:00.00"), ZoneId.systemDefault())
+              .toInstant(),
+          rs.getObject(3, Instant.class));
+    }
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(
+        OffsetDateTime.ofInstant(
+            Timestamp.valueOf("2010-01-12 01:55:12").toInstant(), ZoneId.systemDefault()),
+        rs.getObject(1, OffsetDateTime.class));
+    assertFalse(rs.wasNull());
+
+    LocalDateTime l = LocalDateTime.parse("1000-01-01T01:55:13.212345");
+    assertEquals(
+        OffsetDateTime.of(l, ZoneId.systemDefault().getRules().getOffset(l)),
+        rs.getObject(2, OffsetDateTime.class));
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        OffsetDateTime.ofInstant(
+            Timestamp.valueOf("9999-12-31 18:30:12.55").toInstant(), ZoneId.systemDefault()),
+        rs.getObject(3, OffsetDateTime.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, OffsetDateTime.class));
+    assertTrue(rs.wasNull());
+    if (isMariaDBServer()) {
+      rs.next();
+      assertNull(rs.getObject(1, OffsetDateTime.class));
+      assertNull(rs.getObject(2, OffsetDateTime.class));
+      assertEquals(
+          OffsetDateTime.ofInstant(
+              Timestamp.valueOf("9999-12-31 00:00:00.00").toInstant(), ZoneId.systemDefault()),
+          rs.getObject(3, OffsetDateTime.class));
+    }
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type DATETIME cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws SQLException {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type DATETIME cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws SQLException {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type DATETIME cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBytes(1), "Data type DATETIME cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws SQLException {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type DATETIME cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws SQLException {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type DATETIME cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBlob(1), "Data type DATETIME cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getBigInteger() throws SQLException {
+    getBigInteger(get());
+  }
+
+  @Test
+  public void getBigIntegerPrepared() throws SQLException {
+    getBigInteger(getPrepare(sharedConn));
+    getBigInteger(getPrepare(sharedConnBinary));
+  }
+
+  private void getBigInteger(ResultSet res) {
+    CompleteResult rs = (CompleteResult) res;
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigInteger(1),
+        "Data type DATETIME cannot be decoded as BigInteger");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws SQLException {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getClob(1), "Data type DATETIME cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws SQLException {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getNClob(1), "Data type DATETIME cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("DATETIME", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.sql.Timestamp", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.TIMESTAMP, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    // https://jira.mariadb.org/browse/XPT-273
+    if (!isXpand()) {
+      assertEquals(19, meta.getPrecision(1));
+      assertEquals(19, meta.getColumnDisplaySize(1));
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE DateTimeCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    LocalDateTime ldtNow = LocalDateTime.parse("2022-04-15T19:49:41.398057");
+    OffsetDateTime offsetDtUtc =
+        OffsetDateTime.of(ldtNow, ZoneId.of("UTC").getRules().getOffset(ldtNow));
+    OffsetDateTime offsetDtCurrent =
+        OffsetDateTime.of(ldtNow, ZoneId.systemDefault().getRules().getOffset(ldtNow));
+
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO DateTimeCodec2(t1) VALUES (?)")) {
+      prep.setDate(1, Date.valueOf("2010-01-12"));
+      prep.execute();
+      prep.setDate(1, null);
+      prep.execute();
+      prep.setObject(1, Date.valueOf("2010-01-13"));
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, Date.valueOf("2010-01-14"), Types.DATE);
+      prep.execute();
+      prep.setObject(1, null, Types.DATE);
+      prep.execute();
+      prep.setObject(1, LocalDateTime.parse("2010-01-12T01:55:12.987765"), Types.TIMESTAMP);
+      prep.execute();
+      prep.setObject(1, "2010-01-12 01:55:12.987765", Types.TIMESTAMP);
+      prep.execute();
+      prep.setObject(1, "0000-00-00 00:00:00", Types.TIMESTAMP);
+      prep.execute();
+      prep.setObject(1, LocalDateTime.parse("2010-01-12T01:56:12.456"), Types.TIMESTAMP);
+      prep.execute();
+      prep.setObject(
+          1,
+          LocalDateTime.parse("2011-01-12T01:55:12").atZone(ZoneId.systemDefault()),
+          Types.TIMESTAMP);
+      prep.execute();
+      prep.setObject(
+          1,
+          LocalDateTime.parse("2011-01-12T01:55:12.456").atZone(ZoneId.systemDefault()),
+          Types.TIMESTAMP);
+      prep.execute();
+      prep.setObject(
+          1, LocalDateTime.parse("2012-01-12T01:55:12").atZone(ZoneId.of("UTC")), Types.TIMESTAMP);
+      prep.execute();
+      prep.setObject(
+          1,
+          LocalDateTime.parse("2012-01-12T01:55:12.456").atZone(ZoneId.of("UTC")),
+          Types.TIMESTAMP);
+      prep.execute();
+      prep.setTimestamp(1, Timestamp.valueOf("2015-12-12 01:55:12"));
+      prep.execute();
+      prep.setTimestamp(1, Timestamp.valueOf("2015-12-12 01:55:12.654"));
+      prep.execute();
+      prep.setObject(1, Timestamp.valueOf("2016-12-12 01:55:12"));
+      prep.execute();
+      prep.setObject(1, Timestamp.valueOf("2016-12-12 01:55:12.654"));
+      prep.execute();
+      prep.setObject(1, Instant.ofEpochSecond(10, 654000));
+      prep.execute();
+      prep.setObject(1, Instant.ofEpochSecond(12));
+      prep.execute();
+      prep.setObject(1, offsetDtUtc);
+      prep.execute();
+      prep.setObject(1, offsetDtCurrent);
+      prep.execute();
+      assertThrowsContains(
+          SQLException.class,
+          () -> prep.setObject(1, "2010-aaa", Types.TIMESTAMP),
+          "Could not convert [2010-aaa] to java.sql.Type 93");
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM DateTimeCodec2");
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-12"), rs.getDate(2));
+    rs.updateDate(2, null);
+    rs.updateRow();
+    assertNull(rs.getDate(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateDate(2, Date.valueOf("2011-01-12"));
+    rs.updateRow();
+    assertEquals(Date.valueOf("2011-01-12"), rs.getDate(2));
+
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-13"), rs.getDate(2));
+    rs.updateObject(2, null);
+    rs.updateRow();
+    assertNull(rs.getDate(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject(2, Date.valueOf("2021-01-12"));
+    rs.updateRow();
+    assertEquals(Date.valueOf("2021-01-12"), rs.getDate(2));
+
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2010-01-14"), rs.getDate(2));
+    rs.updateObject(2, LocalDateTime.parse("2021-01-12T01:55:12.347654"), Types.TIMESTAMP);
+    rs.updateRow();
+    assertEquals(
+        LocalDateTime.parse("2021-01-12T01:55:12.347654"), rs.getObject(2, LocalDateTime.class));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateTimestamp(2, Timestamp.valueOf("2015-12-12 01:55:12.654"));
+    rs.updateRow();
+    assertEquals(Timestamp.valueOf("2015-12-12 01:55:12.654"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(
+        LocalDateTime.parse("2010-01-12T01:55:12.987765"), rs.getObject(2, LocalDateTime.class));
+    rs.updateTimestamp("t1", Timestamp.valueOf("2015-12-12 01:55:12.654321"));
+    rs.updateRow();
+    assertEquals(Timestamp.valueOf("2015-12-12 01:55:12.654321"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(
+        LocalDateTime.parse("2010-01-12T01:55:12.987765"), rs.getObject(2, LocalDateTime.class));
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, LocalDateTime.class));
+
+    rs = stmt.executeQuery("SELECT * FROM DateTimeCodec2");
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2011-01-12"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals(Date.valueOf("2021-01-12"), rs.getDate(2));
+    assertTrue(rs.next());
+    assertEquals(
+        LocalDateTime.parse("2021-01-12T01:55:12.347654"), rs.getObject(2, LocalDateTime.class));
+    assertTrue(rs.next());
+    assertEquals(Timestamp.valueOf("2015-12-12 01:55:12.654"), rs.getTimestamp(2));
+
+    assertTrue(rs.next());
+    assertEquals(Timestamp.valueOf("2015-12-12 01:55:12.654321"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(Timestamp.valueOf("2010-01-12 01:55:12.987765"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertTrue(rs.next());
+    assertEquals(
+        LocalDateTime.parse("2010-01-12T01:56:12.456"), rs.getObject(2, LocalDateTime.class));
+
+    assertTrue(rs.next());
+    assertEquals(LocalDateTime.parse("2011-01-12T01:55:12"), rs.getObject(2, LocalDateTime.class));
+    assertTrue(rs.next());
+    assertEquals(
+        LocalDateTime.parse("2011-01-12T01:55:12.456"), rs.getObject(2, LocalDateTime.class));
+    assertTrue(rs.next());
+    assertEquals(
+        LocalDateTime.parse("2012-01-12T01:55:12").atZone(ZoneId.of("UTC")),
+        rs.getObject(2, ZonedDateTime.class).withZoneSameInstant(ZoneId.of("UTC")));
+    assertTrue(rs.next());
+    assertEquals(
+        LocalDateTime.parse("2012-01-12T01:55:12.456").atZone(ZoneId.of("UTC")),
+        rs.getObject(2, ZonedDateTime.class).withZoneSameInstant(ZoneId.of("UTC")));
+
+    assertTrue(rs.next());
+    assertEquals(Timestamp.valueOf("2015-12-12 01:55:12"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(Timestamp.valueOf("2015-12-12 01:55:12.654"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(Timestamp.valueOf("2016-12-12 01:55:12"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(Timestamp.valueOf("2016-12-12 01:55:12.654"), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(Timestamp.from(Instant.ofEpochSecond(10, 654000)), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(Timestamp.from(Instant.ofEpochSecond(12)), rs.getTimestamp(2));
+    assertTrue(rs.next());
+    assertEquals(
+        ldtNow
+            .atZone(ZoneId.of("UTC"))
+            .withZoneSameInstant(ZoneId.systemDefault())
+            .toOffsetDateTime(),
+        rs.getObject(2, OffsetDateTime.class));
+    assertEquals(
+        ldtNow.atZone(ZoneId.of("UTC")).withZoneSameInstant(ZoneId.systemDefault()),
+        rs.getObject(2, ZonedDateTime.class));
+    assertEquals(
+        ldtNow
+            .atZone(ZoneId.of("UTC"))
+            .withZoneSameInstant(ZoneId.systemDefault())
+            .toLocalDateTime(),
+        rs.getObject(2, LocalDateTime.class));
+    assertTrue(rs.next());
+    assertEquals(offsetDtCurrent, rs.getObject(2, OffsetDateTime.class));
+    assertEquals(ldtNow.atZone(ZoneId.systemDefault()), rs.getObject(2, ZonedDateTime.class));
+    assertEquals(ldtNow, rs.getObject(2, LocalDateTime.class));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/DecimalCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/DecimalCodecTest.java
new file mode 100644
index 0000000..3194995
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/DecimalCodecTest.java
@@ -0,0 +1,921 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class DecimalCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS DecimalCodec");
+    stmt.execute("DROP TABLE IF EXISTS DecimalCodec2");
+    stmt.execute("DROP TABLE IF EXISTS DecimalCodec3");
+    stmt.execute("DROP TABLE IF EXISTS DecimalCodec4");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE DecimalCodec (t1 DECIMAL(10,0), t2 DECIMAL(30,6), t3 DECIMAL(10,3), t4"
+            + " DECIMAL(10,0))");
+    stmt.execute(
+        "CREATE TABLE DecimalCodec2 (t1 DECIMAL(10,0), t2 DECIMAL(10,6), t3 DECIMAL(10,3), t4"
+            + " DECIMAL(10,0))");
+    stmt.execute(
+        "INSERT INTO DecimalCodec VALUES (0, 105.21, -1.6, null), (0, 9223372036854775808, 0,"
+            + " null)");
+    stmt.execute(
+        "CREATE TABLE DecimalCodec3 (id int not null primary key auto_increment, t1"
+            + " DECIMAL(10,0))");
+    stmt.execute(
+        "CREATE TABLE DecimalCodec4 (t1 DECIMAL(10,0) ZEROFILL, t2 DECIMAL(10,6) ZEROFILL, t3"
+            + " DECIMAL(10,3) ZEROFILL, t4 DECIMAL(10,0) ZEROFILL)");
+    stmt.execute("INSERT INTO DecimalCodec4 VALUES (0, 105.21, 1.6, null)");
+
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    return get(false);
+  }
+
+  private ResultSet get(boolean zerofill) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DecimalCodec"
+                + (zerofill ? "4" : ""));
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    return getPrepare(con, false);
+  }
+
+  private ResultSet getPrepare(Connection con, boolean zerofill) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DecimalCodec"
+                + (zerofill ? "4" : "")
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("105.210000"), rs.getObject(2));
+    assertEquals(new BigDecimal("105.210000"), rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("-1.600"), rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, LocalTime.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+    getStringZerofill(get(true));
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+    // Xpand doesn't support zerofill https://jira.mariadb.org/browse/XPT-286
+    if (!isXpand()) {
+      getStringZerofill(getPrepare(sharedConn, true));
+      getStringZerofill(getPrepare(sharedConnBinary, true));
+    }
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("105.210000", rs.getString(2));
+    assertEquals("105.210000", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1.600", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  public void getStringZerofill(ResultSet rs) throws SQLException {
+    assertEquals("0000000000", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("0105.210000", rs.getString(2));
+    assertEquals("0105.210000", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("0000001.600", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("105.210000", rs.getNString(2));
+    assertEquals("105.210000", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1.600", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 105, rs.getByte(2));
+    assertEquals((byte) 105, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105, rs.getShort(2));
+    assertEquals(105, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+    assertTrue(rs.next());
+    assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getShort(2),
+        "value '9223372036854775808.000000' cannot be decoded as Short");
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105, rs.getInt(2));
+    assertEquals(105, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+    assertTrue(rs.next());
+    assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getInt(2),
+        "value '9223372036854775808.000000' cannot be decoded as Int");
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105L, rs.getLong(2));
+    assertEquals(105L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+    assertTrue(rs.next());
+    assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getLong(2),
+        "value '9223372036854775808.000000' cannot be decoded as Long");
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105.21F, rs.getFloat(2));
+    assertEquals(105.21F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105.21D, rs.getDouble(2));
+    assertEquals(105.21D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("105.210000"), rs.getBigDecimal(2));
+    assertEquals(new BigDecimal("105.2"), rs.getBigDecimal(2, BigDecimal.ROUND_DOWN));
+    assertEquals(new BigDecimal("105.210000"), rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("-1.600"), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertNull(rs.getBigDecimal(4, BigDecimal.ROUND_CEILING));
+    assertTrue(rs.wasNull());
+    assertTrue(rs.next());
+    assertEquals(new BigDecimal("9223372036854775808.000000"), rs.getBigDecimal(2));
+  }
+
+  @Test
+  public void getBigDecimalScale() throws SQLException {
+    getBigDecimalScale(get());
+  }
+
+  @Test
+  public void getBigDecimalScalePrepare() throws SQLException {
+    getBigDecimalScale(getPrepare(sharedConn));
+    getBigDecimalScale(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getBigDecimalScale(ResultSet rs) throws SQLException {
+    assertEquals(new BigDecimal("0.0"), rs.getBigDecimal(1, 1));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("0.0"), rs.getBigDecimal("t1alias", 1));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("105.2"), rs.getBigDecimal(2, 1));
+    assertEquals(new BigDecimal("105.2"), rs.getBigDecimal("t2alias", 1));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("-1.6"), rs.getBigDecimal(3, 1));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4, 1));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type DECIMAL cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type DECIMAL cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type DECIMAL cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type DECIMAL cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type DECIMAL cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type DECIMAL cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "Type class java.time.OffsetDateTime not supported type for DECIMAL type");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type DECIMAL cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type DECIMAL cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws SQLException {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type DECIMAL cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type DECIMAL cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws SQLException {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type DECIMAL cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type DECIMAL cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type DECIMAL cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type DECIMAL cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws SQLException {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type DECIMAL cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type DECIMAL cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws SQLException {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type DECIMAL cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type DECIMAL cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws SQLException {
+    getRef(get());
+  }
+
+  @Test
+  public void getRefPrepare() throws SQLException {
+    getRef(getPrepare(sharedConn));
+    getRef(getPrepare(sharedConnBinary));
+  }
+
+  public void getRef(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type DECIMAL cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type DECIMAL cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws SQLException {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type DECIMAL cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type DECIMAL cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws SQLException {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob(1),
+        "Data type DECIMAL cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type DECIMAL cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(get());
+  }
+
+  @Test
+  public void getURLPrepare() throws SQLException {
+    getURL(getPrepare(sharedConn));
+    getURL(getPrepare(sharedConnBinary));
+  }
+
+  public void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse '0' as URL");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse '0' as URL");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("DECIMAL", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.math.BigDecimal", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.DECIMAL, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(10, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(11, meta.getColumnDisplaySize(1));
+
+    assertEquals(30, meta.getPrecision(2));
+    assertEquals(6, meta.getScale(2));
+    assertEquals("", meta.getSchemaName(2));
+    assertEquals(32, meta.getColumnDisplaySize(2));
+  }
+
+  @Test
+  public void setParameter() throws SQLException {
+    try (PreparedStatement prep =
+        sharedConn.prepareStatement("INSERT INTO DecimalCodec2 VALUE (?, ?, ?, ?)")) {
+      prep.setBigDecimal(1, new BigDecimal("789.123"));
+      prep.setBigDecimal(2, new BigDecimal("1789.123456"));
+      prep.setNull(3, Types.DECIMAL);
+      prep.setObject(4, new BigDecimal("-211789.987987"));
+      prep.execute();
+      Statement stmt = sharedConn.createStatement();
+      ResultSet rs = stmt.executeQuery("SELECT * FROM DecimalCodec2");
+      rs.next();
+      assertEquals(new BigDecimal("789"), rs.getBigDecimal(1));
+      assertEquals(new BigDecimal("1789.123456"), rs.getBigDecimal(2));
+      assertNull(rs.getBigDecimal(3));
+      assertEquals(new BigDecimal("-211790"), rs.getBigDecimal(4));
+      Common.assertThrowsContains(
+          SQLException.class,
+          () -> prep.setObject(4, this),
+          "Type org.mariadb.jdbc.integration.codec.DecimalCodecTest not supported type");
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE DecimalCodec3");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO DecimalCodec3(t1) VALUES (?)")) {
+      prep.setBigDecimal(1, BigDecimal.valueOf(1));
+      prep.execute();
+      prep.setBigDecimal(1, null);
+      prep.execute();
+      prep.setObject(1, BigDecimal.valueOf(2));
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, BigDecimal.valueOf(3), Types.DECIMAL);
+      prep.execute();
+      prep.setObject(1, "4", Types.DECIMAL);
+      prep.execute();
+      prep.setObject(1, "5", Types.NUMERIC);
+      prep.execute();
+      prep.setObject(1, 7D, JDBCType.NUMERIC);
+      prep.execute();
+      prep.setObject(1, "6", Types.BIGINT);
+      prep.execute();
+      prep.setObject(1, null, Types.DECIMAL);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM DecimalCodec3");
+
+    assertTrue(rs.next());
+    assertEquals("1", rs.getBigDecimal(2).toString());
+    rs.updateBigDecimal(2, null);
+    rs.updateRow();
+    assertNull(rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBigDecimal(2));
+    rs.updateBigDecimal("t1", BigDecimal.ONE);
+    rs.updateRow();
+    assertEquals("1", rs.getBigDecimal(2).toString());
+
+    assertTrue(rs.next());
+    assertEquals("2", rs.getBigDecimal(2).toString());
+    rs.updateObject(2, null);
+    rs.updateRow();
+    assertNull(rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject(2, BigDecimal.valueOf(20));
+    rs.updateRow();
+    assertEquals(BigDecimal.valueOf(20), rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertEquals("3", rs.getBigDecimal(2).toString());
+    rs.updateObject("t1", null, Types.DECIMAL);
+    rs.updateRow();
+    assertNull(rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertEquals("4", rs.getBigDecimal(2).toString());
+
+    assertTrue(rs.next());
+    assertEquals("5", rs.getBigDecimal(2).toString());
+
+    assertTrue(rs.next());
+    assertEquals("7", rs.getBigDecimal(2).toString());
+
+    assertTrue(rs.next());
+    assertEquals("6", rs.getBigDecimal(2).toString());
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject(2, BigDecimal.valueOf(30), Types.DECIMAL);
+    rs.updateRow();
+    assertEquals(BigDecimal.valueOf(30), rs.getBigDecimal(2));
+
+    rs = stmt.executeQuery("SELECT * FROM DecimalCodec3");
+
+    assertTrue(rs.next());
+    assertNull(rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertEquals("1", rs.getBigDecimal(2).toString());
+
+    assertTrue(rs.next());
+    assertNull(rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertEquals(BigDecimal.valueOf(20), rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBigDecimal(2));
+
+    assertTrue(rs.next());
+    assertEquals("4", rs.getBigDecimal(2).toString());
+    assertTrue(rs.next());
+    assertEquals("5", rs.getBigDecimal(2).toString());
+    assertTrue(rs.next());
+    assertEquals("7", rs.getBigDecimal(2).toString());
+    assertTrue(rs.next());
+    assertEquals("6", rs.getBigDecimal(2).toString());
+
+    assertTrue(rs.next());
+    assertEquals(BigDecimal.valueOf(30), rs.getBigDecimal(2));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/DoubleCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/DoubleCodecTest.java
new file mode 100644
index 0000000..b21bf15
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/DoubleCodecTest.java
@@ -0,0 +1,777 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class DoubleCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS DoubleCodec");
+    stmt.execute("DROP TABLE IF EXISTS DoubleCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE DoubleCodec (t1 DOUBLE, t2 DOUBLE, t3 DOUBLE, t4 DOUBLE)");
+    stmt.execute("INSERT INTO DoubleCodec VALUES (0, 105.21, -1.6, null)");
+    stmt.execute(
+        "CREATE TABLE DoubleCodec2 (id int not null primary key auto_increment, t1 DOUBLE)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DoubleCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from DoubleCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals(0d, (double) rs.getObject(1), 0.00001d);
+    assertFalse(rs.wasNull());
+    assertEquals(105.21d, (double) rs.getObject(2), 0.00001d);
+    assertEquals(105.21d, (double) rs.getObject("t2alias"), 0.00001d);
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6d, (double) rs.getObject(3), 0.00001d);
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    //    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    //    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getString() throws Exception {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws Exception {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws Exception {
+    assertTrue("0".equals(rs.getString(1)) || "0.0".equals(rs.getString(1)));
+    assertFalse(rs.wasNull());
+    assertEquals("105.21", rs.getString(2));
+    assertEquals("105.21", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1.6", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws Exception {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws Exception {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws Exception {
+    assertTrue("0".equals(rs.getString(1)) || "0.0".equals(rs.getString(1)));
+    assertFalse(rs.wasNull());
+    assertEquals("105.21", rs.getNString(2));
+    assertEquals("105.21", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1.6", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws Exception {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws Exception {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws Exception {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws Exception {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws Exception {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws Exception {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 105, rs.getByte(2));
+    assertEquals((byte) 105, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws Exception {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws Exception {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws Exception {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105, rs.getShort(2));
+    assertEquals(105, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws Exception {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws Exception {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws Exception {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105, rs.getInt(2));
+    assertEquals(105, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws Exception {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws Exception {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws Exception {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105L, rs.getLong(2));
+    assertEquals(105L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws Exception {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws Exception {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws Exception {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105.21F, rs.getFloat(2));
+    assertEquals(105.21F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws Exception {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws Exception {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws Exception {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105.21D, rs.getDouble(2));
+    assertEquals(105.21D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws Exception {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws Exception {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws Exception {
+    assertTrue(
+        BigDecimal.ZERO.equals(rs.getBigDecimal(1))
+            || new BigDecimal("0.0").equals(rs.getBigDecimal(1)));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("105.21"), rs.getBigDecimal(2));
+    assertEquals(new BigDecimal("105.21"), rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("-1.6"), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws Exception {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws Exception {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type DOUBLE cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type DOUBLE cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws Exception {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws Exception {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type DOUBLE cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type DOUBLE cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws Exception {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws Exception {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type DOUBLE cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type DOUBLE cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "Type class java.time.OffsetDateTime not supported type for DOUBLE type");
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type DOUBLE cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type DOUBLE cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type DOUBLE cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type DOUBLE cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type DOUBLE cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type DOUBLE cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws Exception {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws Exception {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type DOUBLE cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type DOUBLE cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type DOUBLE cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type DOUBLE cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type DOUBLE cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type DOUBLE cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws Exception {
+    getRef(get());
+  }
+
+  @Test
+  public void getRefPrepare() throws Exception {
+    getRef(getPrepare(sharedConn));
+    getRef(getPrepare(sharedConnBinary));
+  }
+
+  public void getRef(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type DOUBLE cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type DOUBLE cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type DOUBLE cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type DOUBLE cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getNClob(1), "Data type DOUBLE cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type DOUBLE cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getURL() throws Exception {
+    getURL(get());
+  }
+
+  @Test
+  public void getURLPrepare() throws Exception {
+    getURL(getPrepare(sharedConn));
+    getURL(getPrepare(sharedConnBinary));
+  }
+
+  public void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("DOUBLE", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Double", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.DOUBLE, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals("", meta.getSchemaName(1));
+    // https://jira.mariadb.org/browse/XPT-276
+    if (!isXpand()) {
+      assertEquals(22, meta.getColumnDisplaySize(1));
+      assertEquals(22, meta.getPrecision(1));
+      assertEquals(31, meta.getScale(1));
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE DoubleCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO DoubleCodec2(t1) VALUES (?)")) {
+      prep.setDouble(1, 1D);
+      prep.execute();
+      prep.setObject(1, 2D);
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, 3D, Types.DECIMAL);
+      prep.execute();
+      prep.setObject(1, "4", Types.FLOAT);
+      prep.execute();
+      prep.setObject(1, 5D, Types.DOUBLE);
+      prep.execute();
+      prep.setObject(1, null, Types.DECIMAL);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM DoubleCodec2");
+    assertTrue(rs.next());
+    assertEquals(1D, rs.getDouble(2));
+    rs.updateDouble("t1", 10D);
+    rs.updateRow();
+    assertEquals(10D, rs.getDouble(2));
+
+    assertTrue(rs.next());
+    assertEquals(2D, rs.getDouble(2));
+    rs.updateObject(2, null);
+    rs.updateRow();
+    assertNull(rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject("t1", 20D);
+    rs.updateRow();
+    assertEquals(20D, rs.getDouble(2));
+
+    assertTrue(rs.next());
+    assertEquals(3D, rs.getDouble(2));
+    rs.updateObject(2, null, Types.DECIMAL);
+    rs.updateRow();
+    assertNull(rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals(4D, rs.getDouble(2));
+    assertTrue(rs.next());
+    assertEquals(5D, rs.getDouble(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject("t1", 30D, Types.DECIMAL);
+    rs.updateRow();
+    assertEquals(30D, rs.getDouble(2));
+
+    rs = stmt.executeQuery("SELECT * FROM DoubleCodec2");
+    assertTrue(rs.next());
+    assertEquals(10D, rs.getDouble(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals(20D, rs.getDouble(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals(4D, rs.getDouble(2));
+    assertTrue(rs.next());
+    assertEquals(5D, rs.getDouble(2));
+
+    assertTrue(rs.next());
+    assertEquals(30D, rs.getDouble(2));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/EnumCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/EnumCodecTest.java
new file mode 100644
index 0000000..75bbf70
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/EnumCodecTest.java
@@ -0,0 +1,770 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class EnumCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS EnumCodec");
+    stmt.execute("DROP TABLE IF EXISTS EnumCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE EnumCodec (t1 ENUM('0', '1', 'some🌟', '2011-01-01', '2010-12-31"
+            + " 23:59:59.152', '23:54:51.840010'), t2 ENUM('0', '1', 'some🌟', '2011-01-01',"
+            + " '2010-12-31 23:59:59.152', '23:54:51.840010'),  t3 ENUM('0', '1', 'some🌟',"
+            + " '2011-01-01', '2010-12-31 23:59:59.152', '23:54:51.840010'), t4 ENUM('0', '1',"
+            + " 'some🌟', '2011-01-01', '2010-12-31 23:59:59.152', '23:54:51.840010')) CHARACTER"
+            + " SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+    stmt.execute(
+        "INSERT INTO EnumCodec VALUES ('0', '1', 'some🌟', null), ('2011-01-01', '2010-12-31"
+            + " 23:59:59.152', '23:54:51.840010', null)");
+    stmt.execute("CREATE TABLE EnumCodec2 (t1 ENUM('0', '1', '2')) CHARACTER SET binary");
+    stmt.execute("INSERT INTO EnumCodec2 VALUES ('0'), ('1'), (null)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from EnumCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from EnumCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getObject(2));
+    assertEquals("1", rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  private ResultSet getBinary() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs = stmt.executeQuery("select t1 as t1alias from EnumCodec2");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getBinaryPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement("select t1 as t1alias from EnumCodec2" + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getBinaryObject() throws SQLException {
+    getBinaryObject(getBinary());
+  }
+
+  @Test
+  public void getBinaryObjectPrepare() throws SQLException {
+    getBinaryObject(getBinaryPrepare(sharedConn));
+    getBinaryObject(getBinaryPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryObject(ResultSet rs) throws SQLException {
+    assertArrayEquals("0".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.next());
+    assertArrayEquals("1".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.wasNull());
+    assertTrue(rs.next());
+    assertNull(rs.getObject(1));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testArrObject(rs, new byte[] {(byte) '0'});
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testObject(rs, Clob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, NClob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, InputStream.class, new MariaDbClob("0".getBytes()).getBinaryStream());
+    testObject(rs, Reader.class, new StringReader("0"));
+    rs.next();
+    testObject(rs, LocalDate.class, LocalDate.parse("2011-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2011-01-01T00:00"));
+    testObject(rs, LocalTime.class, LocalTime.parse("23:54:51.840010"), 3);
+    Time t = Time.valueOf("23:54:51");
+    testObject(rs, Time.class, new Time(t.getTime() + 840), 3);
+    testObject(rs, Date.class, Date.valueOf("2011-01-01"));
+    Timestamp tt = Timestamp.valueOf("2010-12-31 23:59:59");
+    testObject(rs, Timestamp.class, new Timestamp(tt.getTime() + 152), 2);
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2011-01-01T00:00").atZone(ZoneId.systemDefault()));
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-12-31"), 2);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getByte(3), " cannot be decoded as Byte");
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getShort(3), "value 'some🌟' cannot be decoded as Short");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(3), "value 'some🌟' cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getLong(3),
+        "value 'some\uD83C\uDF1F' cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(3), "value 'some🌟' cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(3),
+        "value 'some🌟' cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(3),
+        "value 'some🌟' cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), " cannot be decoded as Date");
+    rs.next();
+    assertEquals("2011-01-01", rs.getDate(1).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate(2).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate("t2alias").toString());
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(3), " cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "STRING value '2011-01-01' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(2),
+        "STRING value '2010-12-31 23:59:59.152' cannot be decoded as Time");
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(3).getTime());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime("t3alias").getTime());
+    Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+    assertEquals(86091840, rs.getTime(3, utc).getTime());
+    assertEquals(86091840, rs.getTime("t3alias", utc).getTime());
+
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    rs.next();
+
+    assertEquals(Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152, rs.getTimestamp(2).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152,
+        rs.getTimestamp("t2alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t2alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    //
+    //    ('2011-01-01', '2010-12-31 23:59:59.152',"
+    //            + " '23:54:51.840010', null)
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getAsciiStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getAsciiStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getAsciiStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getUnicodeStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)),
+        rs.getUnicodeStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getUnicodeStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getBinaryStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBinaryStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBinaryStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) throws SQLException {
+    assertArrayEquals("0".getBytes(), rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(), rs.getBytes(2));
+    assertArrayEquals("1".getBytes(), rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBytes(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getNCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getNCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getBlob(1), " (not binary) cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getNClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getNClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    if (isXpand()) {
+      assertEquals("TEXT", meta.getColumnTypeName(1));
+      assertEquals(Types.VARCHAR, meta.getColumnType(1));
+      assertEquals(65535, meta.getPrecision(1));
+      assertEquals(65535, meta.getColumnDisplaySize(1));
+    } else {
+      assertEquals("CHAR", meta.getColumnTypeName(1));
+      assertEquals(Types.CHAR, meta.getColumnType(1));
+      assertEquals(23, meta.getPrecision(1));
+      assertEquals(23, meta.getColumnDisplaySize(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.String", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/FloatCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/FloatCodecTest.java
new file mode 100644
index 0000000..11e9816
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/FloatCodecTest.java
@@ -0,0 +1,795 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class FloatCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS FloatCodec");
+    stmt.execute("DROP TABLE IF EXISTS FloatCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE FloatCodec (t1 FLOAT, t2 FLOAT, t3 FLOAT, t4 FLOAT)");
+    stmt.execute("INSERT INTO FloatCodec VALUES (0, 105.21, -1.6, null)");
+    stmt.execute("CREATE TABLE FloatCodec2 (id int not null primary key auto_increment, t1 FLOAT)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from FloatCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from FloatCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals(0f, (float) rs.getObject(1), 0.00001f);
+    assertFalse(rs.wasNull());
+    assertEquals(105.21f, (float) rs.getObject(2), 0.00001f);
+    assertEquals(105.21f, (float) rs.getObject("t2alias"), 0.00001f);
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6f, (float) rs.getObject(3), 0.00001f);
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    //    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    //    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    String s = rs.getString(1);
+    assertTrue("0".equals(s) || "0.0".equals(s));
+    assertFalse(rs.wasNull());
+    assertEquals("105.21", rs.getString(2));
+    assertEquals("105.21", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1.6", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    String s = rs.getNString(1);
+    assertTrue("0".equals(s) || "0.0".equals(s));
+    assertFalse(rs.wasNull());
+    assertEquals("105.21", rs.getNString(2));
+    assertEquals("105.21", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1.6", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 105, rs.getByte(2));
+    assertEquals((byte) 105, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105, rs.getShort(2));
+    assertEquals(105, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105, rs.getInt(2));
+    assertEquals(105, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105L, rs.getLong(2));
+    assertEquals(105L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105.21F, rs.getFloat(2));
+    assertEquals(105.21F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(105.21D, rs.getDouble(2), 0.01D);
+    assertEquals(105.21D, rs.getDouble("t2alias"), 0.01D);
+    assertFalse(rs.wasNull());
+    assertEquals(-1.6D, rs.getDouble(3), 0.01D);
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    BigDecimal b = rs.getBigDecimal(1);
+    assertTrue(BigDecimal.ZERO.equals(b) || new BigDecimal("0.0").equals(b));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("105.21"), rs.getBigDecimal(2).setScale(2, RoundingMode.HALF_DOWN));
+    assertEquals(
+        new BigDecimal("105.21"), rs.getBigDecimal("t2alias").setScale(2, RoundingMode.HALF_DOWN));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("-1.6"), rs.getBigDecimal(3).setScale(1, RoundingMode.HALF_DOWN));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type FLOAT cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type FLOAT cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type FLOAT cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type FLOAT cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type FLOAT cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type FLOAT cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "Type class java.time.OffsetDateTime not supported type for FLOAT type");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type FLOAT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type FLOAT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws SQLException {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type FLOAT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type FLOAT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws SQLException {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type FLOAT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type FLOAT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type FLOAT cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type FLOAT cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws SQLException {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type FLOAT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type FLOAT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws SQLException {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type FLOAT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type FLOAT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws SQLException {
+    ResultSet rs = get();
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type FLOAT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type FLOAT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws SQLException {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type FLOAT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type FLOAT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws SQLException {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getNClob(1), "Data type FLOAT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type FLOAT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getArray() throws SQLException {
+    ResultSet rs = get();
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getArray(1), "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getArray("t1alias"),
+        "Method ResultSet.getArray not supported");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(get());
+  }
+
+  @Test
+  public void getURLPrepare() throws SQLException {
+    getURL(getPrepare(sharedConn));
+    getURL(getPrepare(sharedConnBinary));
+  }
+
+  public void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse");
+  }
+
+  @Test
+  public void getSQLXML() throws SQLException {
+    ResultSet rs = get();
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getSQLXML(1), "Method ResultSet.getSQLXML not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getSQLXML("t1alias"),
+        "Method ResultSet.getSQLXML not supported");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("FLOAT", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Float", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.REAL, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    // https://jira.mariadb.org/browse/XPT-276
+    if (!isXpand()) {
+      assertEquals(12, meta.getPrecision(1));
+      assertEquals(12, meta.getColumnDisplaySize(1));
+      assertEquals(31, meta.getScale(1));
+    }
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE FloatCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO FloatCodec2(t1) VALUES (?)")) {
+      prep.setFloat(1, 1.1F);
+      prep.execute();
+      prep.setObject(1, 2.1F);
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, 3.1F, Types.DECIMAL);
+      prep.execute();
+      prep.setObject(1, "3.2", Types.REAL);
+      prep.execute();
+      prep.setObject(1, 3.3F, Types.REAL);
+      prep.execute();
+      prep.setObject(1, null, Types.DECIMAL);
+      prep.execute();
+    }
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM FloatCodec2");
+    assertTrue(rs.next());
+    assertEquals(1.1F, rs.getFloat(2));
+    rs.updateFloat(2, 4.4f);
+    rs.updateRow();
+    assertEquals(4.4F, rs.getFloat(2));
+
+    assertTrue(rs.next());
+    assertEquals(2.1F, rs.getFloat(2));
+    rs.updateFloat("t1", 5.4f);
+    rs.updateRow();
+    assertEquals(5.4F, rs.getFloat(2));
+
+    assertTrue(rs.next());
+    assertEquals(0F, rs.getFloat(2));
+    assertTrue(rs.wasNull());
+    rs.updateObject(2, 5.1F, Types.DECIMAL);
+    rs.updateRow();
+    assertEquals(5.1F, rs.getFloat(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(3.1F, rs.getFloat(2));
+    rs.updateObject("t1", null, Types.DECIMAL);
+    rs.updateRow();
+    assertEquals(0F, rs.getFloat(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(3.2F, rs.getFloat(2));
+    assertTrue(rs.next());
+    assertEquals(3.3F, rs.getFloat(2));
+
+    assertTrue(rs.next());
+    assertEquals(0F, rs.getFloat(2));
+    assertTrue(rs.wasNull());
+
+    rs = stmt.executeQuery("SELECT * FROM FloatCodec2");
+    assertTrue(rs.next());
+    assertEquals(4.4F, rs.getFloat(2));
+
+    assertTrue(rs.next());
+    assertEquals(5.4F, rs.getFloat(2));
+
+    assertTrue(rs.next());
+    assertEquals(5.1F, rs.getFloat(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0F, rs.getFloat(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(3.2F, rs.getFloat(2));
+    assertTrue(rs.next());
+    assertEquals(3.3F, rs.getFloat(2));
+
+    assertTrue(rs.next());
+    assertEquals(0F, rs.getFloat(2));
+    assertTrue(rs.wasNull());
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/GeometryCollectionCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/GeometryCollectionCodecTest.java
new file mode 100644
index 0000000..548a8ef
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/GeometryCollectionCodecTest.java
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.type.*;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class GeometryCollectionCodecTest extends CommonCodecTest {
+  public static org.mariadb.jdbc.Connection geoConn;
+
+  final GeometryCollection geo1 =
+      new GeometryCollection(
+          new Geometry[] {
+            new Point(0, 0),
+            new LineString(
+                new Point[] {
+                  new Point(10, 10),
+                  new Point(20, 10),
+                  new Point(20, 20),
+                  new Point(10, 20),
+                  new Point(10, 10)
+                },
+                true)
+          });
+  final GeometryCollection geo2 =
+      new GeometryCollection(
+          new Geometry[] {
+            new Polygon(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(0, 0),
+                        new Point(50, 0),
+                        new Point(50, 50),
+                        new Point(0, 50),
+                        new Point(0, 0)
+                      },
+                      false),
+                  new LineString(
+                      new Point[] {
+                        new Point(10, 10),
+                        new Point(20, 10),
+                        new Point(20, 20),
+                        new Point(10, 20),
+                        new Point(10, 10)
+                      },
+                      false)
+                }),
+            new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)})
+          });
+  final GeometryCollection geo3 =
+      new GeometryCollection(
+          new Geometry[] {
+            new MultiLineString(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(0, 0), new Point(50, 0), new Point(50, 50), new Point(0, 50)
+                      },
+                      true),
+                  new LineString(
+                      new Point[] {
+                        new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(10, 20)
+                      },
+                      true)
+                }),
+            new MultiPolygon(
+                new Polygon[] {
+                  new Polygon(
+                      new LineString[] {
+                        new LineString(
+                            new Point[] {
+                              new Point(1, 1),
+                              new Point(1, 8),
+                              new Point(4, 9),
+                              new Point(6, 9),
+                              new Point(9, 3),
+                              new Point(7, 2),
+                              new Point(1, 1)
+                            },
+                            false),
+                      })
+                })
+          });
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    // xpand doesn't recognized GeometryCollection
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE GeometryCollectionCodec (t1 GeometryCollection, t2 GeometryCollection, t3"
+            + " GeometryCollection, t4 GeometryCollection)");
+    stmt.execute(
+        "INSERT INTO GeometryCollectionCodec VALUES (ST_GeomFromText('GeometryCollection(POINT (0"
+            + " 0), LINESTRING(10 10,20 10,20 20,10 20,10 10))'),"
+            + " ST_GeomFromText('GeometryCollection(POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20"
+            + " 10,20 20,10 20,10 10)), MULTIPOINT(0 0,0 10,10 0))'),"
+            + " ST_GeomFromText('GeometryCollection(MULTILINESTRING((0 0,50 0,50 50,0 50), (10"
+            + " 10,20 10,20 20,10 20)), MULTIPOLYGON(((1 1, 1 8,4 9,6 9,9 3,7 2, 1 1))))'), null)");
+    stmt.execute(
+        "CREATE TABLE GeometryCollectionCodec2 (id int not null primary key auto_increment, t1"
+            + " GeometryCollection)");
+    stmt.execute("FLUSH TABLES");
+    String binUrl =
+        mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default";
+    geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl);
+  }
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS GeometryCollectionCodec");
+    stmt.execute("DROP TABLE IF EXISTS GeometryCollectionCodec2");
+    if (geoConn != null) geoConn.close();
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " GeometryCollectionCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " GeometryCollectionCodec WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get(), false);
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn), false);
+    getObject(getPrepare(sharedConnBinary), false);
+    getObject(getPrepare(geoConn), true);
+  }
+
+  public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException {
+    if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals(geo1, rs.getObject(1));
+      assertFalse(rs.wasNull());
+      assertEquals(geo2, rs.getObject(2));
+      assertFalse(rs.wasNull());
+      assertEquals(geo3, rs.getObject(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    } else {
+      assertEquals(geo1, rs.getObject(1, GeometryCollection.class));
+      assertFalse(rs.wasNull());
+      assertEquals(geo2, rs.getObject(2, GeometryCollection.class));
+      assertFalse(rs.wasNull());
+      assertEquals(geo3, rs.getObject(3, GeometryCollection.class));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class, 1);
+    testErrObject(rs, String.class, 1);
+    testErrObject(rs, Long.class, 1);
+    testErrObject(rs, Short.class, 1);
+    testErrObject(rs, BigDecimal.class, 1);
+    testErrObject(rs, BigInteger.class, 1);
+    testErrObject(rs, LineString.class, 1);
+    testErrObject(rs, Point.class, 1);
+    testErrObject(rs, Polygon.class, 1);
+    testErrObject(rs, MultiLineString.class, 1);
+    testErrObject(rs, MultiPoint.class, 1);
+    testErrObject(rs, MultiPolygon.class, 1);
+    testErrObject(rs, Double.class, 1);
+    testErrObject(rs, Float.class, 1);
+    testErrObject(rs, Byte.class, 1);
+
+    String hexa =
+        "000000000107000000020000000101000000000000000000000000000000000000000102000000050000000000000000002440000000000000244000000000000034400000000000002440000000000000344000000000000034400000000000002440000000000000344000000000000024400000000000002440";
+    testArrObject(rs, MultiPolygonCodecTest.decodeHexString(hexa), 1);
+
+    testErrObject(rs, Boolean.class, 1);
+    testErrObject(rs, Clob.class, 1);
+    testErrObject(rs, NClob.class, 1);
+    testErrObject(rs, InputStream.class, 1);
+    testErrObject(rs, Reader.class, 1);
+    testErrObject(rs, java.util.Date.class, 1);
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    getMetaData(sharedConn, false);
+    try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) {
+      getMetaData(con, true);
+    }
+  }
+
+  private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault)
+      throws SQLException {
+    ResultSet rs = getPrepare(con);
+    ResultSetMetaData meta = rs.getMetaData();
+    if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals("GEOMETRYCOLLECTION", meta.getColumnTypeName(1));
+    } else {
+      assertEquals("GEOMETRY", meta.getColumnTypeName(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals(
+        geoDefault ? GeometryCollection.class.getName() : "byte[]", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE GeometryCollectionCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO GeometryCollectionCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, geo1);
+      prep.execute();
+      prep.setObject(1, (GeometryCollection) null);
+      prep.execute();
+
+      prep.setObject(1, geo2);
+      prep.addBatch();
+      prep.setObject(1, geo3);
+      prep.addBatch();
+      prep.executeBatch();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM GeometryCollectionCodec2");
+    assertTrue(rs.next());
+    assertEquals(geo1, rs.getObject(2, GeometryCollection.class));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getObject(2, GeometryCollection.class));
+
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, GeometryCollection.class));
+    rs.updateObject(2, geo2);
+    rs.updateRow();
+    assertEquals(geo2, rs.getObject(2, GeometryCollection.class));
+    assertTrue(rs.next());
+
+    assertEquals(geo2, rs.getObject(2, GeometryCollection.class));
+    assertTrue(rs.next());
+    assertEquals(geo3, rs.getObject(2, GeometryCollection.class));
+    con.commit();
+  }
+
+  @Test
+  public void equal() {
+    assertEquals(geo1, geo1);
+    assertEquals(
+        new GeometryCollection(
+            new Geometry[] {
+              new Point(0, 0),
+              new LineString(
+                  new Point[] {
+                    new Point(10, 10),
+                    new Point(20, 10),
+                    new Point(20, 20),
+                    new Point(10, 20),
+                    new Point(10, 10)
+                  },
+                  true)
+            }),
+        geo1);
+    assertEquals(
+        new GeometryCollection(
+                new Geometry[] {
+                  new Point(0, 0),
+                  new LineString(
+                      new Point[] {
+                        new Point(10, 10),
+                        new Point(20, 10),
+                        new Point(20, 20),
+                        new Point(10, 20),
+                        new Point(10, 10)
+                      },
+                      true)
+                })
+            .hashCode(),
+        geo1.hashCode());
+    assertFalse(geo1.equals(null));
+    assertFalse(geo1.equals(""));
+    assertNotEquals(
+        new GeometryCollection(
+            new Geometry[] {
+              new Point(0, 10),
+              new LineString(
+                  new Point[] {
+                    new Point(10, 10),
+                    new Point(20, 10),
+                    new Point(20, 20),
+                    new Point(10, 20),
+                    new Point(10, 10)
+                  },
+                  true)
+            }),
+        geo1);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/IntCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/IntCodecTest.java
new file mode 100644
index 0000000..ea91e5b
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/IntCodecTest.java
@@ -0,0 +1,1083 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class IntCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS IntCodec");
+    stmt.execute("DROP TABLE IF EXISTS IntCodecUnsigned");
+    stmt.execute("DROP TABLE IF EXISTS IntCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE IntCodec (t1 int, t2 int, t3 int, t4 int)");
+    stmt.execute(
+        "CREATE TABLE IntCodecUnsigned (t1 INT UNSIGNED, t2 INT UNSIGNED, t3 INT UNSIGNED, t4 INT "
+            + "UNSIGNED)");
+    stmt.execute("INSERT INTO IntCodec VALUES (0, 1, -1, null)");
+    stmt.execute("INSERT INTO IntCodecUnsigned VALUES (0, 1, 4294967295, null)");
+    stmt.execute("CREATE TABLE IntCodec2 (id int not null primary key auto_increment, t1 int)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet getSigned() throws SQLException {
+    return get("IntCodec");
+  }
+
+  private ResultSet getUnsigned() throws SQLException {
+    return get("IntCodecUnsigned");
+  }
+
+  private ResultSet get(String table) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from " + table);
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPreparedSigned(Connection con) throws SQLException {
+    return getPrepare(con, "IntCodec");
+  }
+
+  private ResultSet getPreparedUnsigned(Connection con) throws SQLException {
+    return getPrepare(con, "IntCodecUnsigned");
+  }
+
+  private ResultSet getPrepare(Connection con, String table) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4"
+                + " as t4alias from "
+                + table
+                + " WHERE 1 > ?")) {
+      preparedStatement.setInt(1, 0);
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      return rs;
+    } finally {
+      con.commit();
+    }
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(getSigned());
+  }
+
+  @Test
+  public void getObjectPrepared() throws SQLException {
+    getObject(getPreparedSigned(sharedConn));
+    getObject(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getObject(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getObject(2));
+    assertEquals(1, rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(4, int.class),
+        "Cannot return null for primitive int");
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(getSigned());
+  }
+
+  @Test
+  public void getObjectTypePrepared() throws Exception {
+    getObjectType(getPreparedSigned(sharedConn));
+    getObjectType(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    rs.next();
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(getSigned());
+  }
+
+  @Test
+  public void getStringPrepared() throws SQLException {
+    getString(getPreparedSigned(sharedConn));
+    getString(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getStringUnsigned() throws SQLException {
+    getStringUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getStringUnsignedPrepared() throws SQLException {
+    getStringUnsigned(getPreparedUnsigned(sharedConn));
+    getStringUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getStringUnsigned(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("4294967295", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(getSigned());
+  }
+
+  @Test
+  public void getNStringPrepared() throws SQLException {
+    getNString(getPreparedSigned(sharedConn));
+    getNString(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(getSigned());
+  }
+
+  @Test
+  public void getBooleanPrepared() throws SQLException {
+    getBoolean(getPreparedSigned(sharedConn));
+    getBoolean(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertFalse(rs.getBoolean("t4alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(getSigned());
+  }
+
+  @Test
+  public void getBytePrepared() throws SQLException {
+    getByte(getPreparedSigned(sharedConn));
+    getByte(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertEquals((byte) 0, rs.getByte("t4alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnsignedByte() throws SQLException {
+    getUnsignedByte(getUnsigned());
+  }
+
+  @Test
+  public void getUnsignedBytePrepared() throws SQLException {
+    getUnsignedByte(getPreparedUnsigned(sharedConn));
+    getUnsignedByte(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getUnsignedByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(SQLDataException.class, () -> rs.getByte(3), "byte overflow");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(getSigned());
+  }
+
+  @Test
+  public void getShortPrepared() throws SQLException {
+    getShort(getPreparedSigned(sharedConn));
+    getShort(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertEquals(0, rs.getShort("t4alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(getSigned());
+  }
+
+  @Test
+  public void getIntPrepared() throws SQLException {
+    getInt(getPreparedSigned(sharedConn));
+    getInt(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getIntUnsigned() throws SQLException {
+    getIntUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getIntUnsignedPrepared() throws SQLException {
+    getIntUnsigned(getPreparedUnsigned(sharedConn));
+    getIntUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getIntUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(SQLDataException.class, () -> rs.getInt(3), "integer overflow");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(getSigned());
+  }
+
+  @Test
+  public void getLongPrepared() throws SQLException {
+    getLong(getPreparedSigned(sharedConn));
+    getLong(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertEquals(0L, rs.getLong("t4alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLongUnsigned() throws SQLException {
+    getLongUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getLongUnsignedPrepared() throws SQLException {
+    getLongUnsigned(getPreparedUnsigned(sharedConn));
+    getLongUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getLongUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(4294967295L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(getSigned());
+  }
+
+  @Test
+  public void getFloatPrepared() throws SQLException {
+    getFloat(getPreparedSigned(sharedConn));
+    getFloat(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertEquals(0F, rs.getFloat("t4alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloatUnsigned() throws SQLException {
+    getFloatUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getFloatUnsignedPrepared() throws SQLException {
+    getFloatUnsigned(getPreparedUnsigned(sharedConn));
+    getFloatUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getFloatUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(4294967295F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(getSigned());
+  }
+
+  @Test
+  public void getDoublePrepared() throws SQLException {
+    getDouble(getPreparedSigned(sharedConn));
+    getDouble(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertEquals(0D, rs.getDouble("t4alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDoubleUnsigned() throws SQLException {
+    getDoubleUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getDoubleUnsignedPrepared() throws SQLException {
+    getDoubleUnsigned(getPreparedUnsigned(sharedConn));
+    getDoubleUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getDoubleUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(4294967295D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(getSigned());
+  }
+
+  @Test
+  public void getBigDecimalPrepared() throws SQLException {
+    getBigDecimal(getPreparedSigned(sharedConn));
+    getBigDecimal(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(-1), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertNull(rs.getBigDecimal("t4alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimalUnsigned() throws SQLException {
+    getBigDecimalUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigDecimalUnsignedPrepared() throws SQLException {
+    getBigDecimalUnsigned(getPreparedUnsigned(sharedConn));
+    getBigDecimalUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getBigDecimalUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(4294967295L), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigInteger() throws SQLException {
+    getBigInteger(getSigned());
+  }
+
+  @Test
+  public void getBigIntegerPrepared() throws SQLException {
+    getBigInteger(getPreparedSigned(sharedConn));
+    getBigInteger(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBigInteger(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertEquals(BigInteger.ZERO, rs.getBigInteger(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getBigInteger(2));
+    assertEquals(BigInteger.ONE, rs.getBigInteger("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(-1), rs.getBigInteger(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigInteger(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigIntegerUnsigned() throws SQLException {
+    getBigIntegerUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigIntegerUnsignedPrepared() throws SQLException {
+    getBigIntegerUnsigned(getPreparedUnsigned(sharedConn));
+    getBigIntegerUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getBigIntegerUnsigned(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertEquals(BigInteger.ZERO, rs.getBigInteger(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getBigInteger(2));
+    assertEquals(BigInteger.ONE, rs.getBigInteger("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(4294967295L), rs.getBigInteger(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigInteger(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(getSigned());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPreparedSigned(sharedConn));
+    getDuration(getPreparedSigned(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, Duration.class),
+        "Type class java.time.Duration not supported type for INTEGER type");
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(getSigned());
+  }
+
+  @Test
+  public void getDatePrepared() throws SQLException {
+    getDate(getPreparedSigned(sharedConn));
+    getDate(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type INTEGER cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type INTEGER cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(getSigned());
+  }
+
+  @Test
+  public void getTimePrepared() throws SQLException {
+    getTime(getPreparedSigned(sharedConn));
+    getTime(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type INTEGER cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type INTEGER cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(getSigned());
+  }
+
+  @Test
+  public void getTimestampPrepared() throws SQLException {
+    getTimestamp(getPreparedSigned(sharedConn));
+    getTimestamp(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type INTEGER cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type INTEGER cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(getSigned());
+  }
+
+  @Test
+  public void getAsciiStreamPrepared() throws SQLException {
+    getAsciiStream(getPreparedSigned(sharedConn));
+    getAsciiStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type INTEGER cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type INTEGER cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(getSigned());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepared() throws SQLException {
+    getUnicodeStream(getPreparedSigned(sharedConn));
+    getUnicodeStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  private void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type INTEGER cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type INTEGER cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(getSigned());
+  }
+
+  @Test
+  public void getBinaryStreamPrepared() throws SQLException {
+    getBinaryStream(getPreparedSigned(sharedConn));
+    getBinaryStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type INTEGER cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type INTEGER cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(getSigned());
+  }
+
+  @Test
+  public void getBytesPrepared() throws SQLException {
+    getBytes(getPreparedSigned(sharedConn));
+    getBytes(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type INTEGER cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type INTEGER cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getCharacterStreamPrepared() throws SQLException {
+    getCharacterStream(getPreparedSigned(sharedConn));
+    getCharacterStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type INTEGER cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type INTEGER cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepared() throws SQLException {
+    getNCharacterStream(getPreparedSigned(sharedConn));
+    getNCharacterStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type INTEGER cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type INTEGER cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws SQLException {
+    getRef(getSigned());
+  }
+
+  @Test
+  public void getRefPrepared() throws SQLException {
+    getRef(getPreparedSigned(sharedConn));
+    getRef(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getRef(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(getSigned());
+  }
+
+  @Test
+  public void getBlobPrepared() throws SQLException {
+    getBlob(getPreparedSigned(sharedConn));
+    getBlob(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type INTEGER cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type INTEGER cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(getSigned());
+  }
+
+  @Test
+  public void getClobPrepared() throws SQLException {
+    getClob(getPreparedSigned(sharedConn));
+    getClob(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type INTEGER cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type INTEGER cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(getSigned());
+  }
+
+  @Test
+  public void getNClobPrepared() throws SQLException {
+    getNClob(getPreparedSigned(sharedConn));
+    getNClob(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob(1),
+        "Data type INTEGER cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type INTEGER cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getArray() throws SQLException {
+    getArray(getSigned());
+  }
+
+  @Test
+  public void getArrayPrepared() throws SQLException {
+    getArray(getPreparedSigned(sharedConn));
+    getArray(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getArray(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getArray(1), "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getArray("t1alias"),
+        "Method ResultSet.getArray not supported");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(getSigned());
+  }
+
+  @Test
+  public void getURLPrepared() throws SQLException {
+    getURL(getPreparedSigned(sharedConn));
+    getURL(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse '0' as URL");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse '0' as URL");
+  }
+
+  @Test
+  public void getSQLXML() throws SQLException {
+    getSQLXML(getSigned());
+  }
+
+  @Test
+  public void getSQLXMLPrepared() throws SQLException {
+    getSQLXML(getPreparedSigned(sharedConn));
+    getSQLXML(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getSQLXML(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getSQLXML(1), "Method ResultSet.getSQLXML not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getSQLXML("t1alias"),
+        "Method ResultSet.getSQLXML not supported");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = getSigned();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("INTEGER", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Integer", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.INTEGER, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(11, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(11, meta.getColumnDisplaySize(1));
+
+    rs = getUnsigned();
+    meta = rs.getMetaData();
+    assertEquals("INTEGER UNSIGNED", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Long", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.BIGINT, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+
+    // https://jira.mariadb.org/browse/XPT-276
+    if (!isXpand()) {
+      assertEquals(10, meta.getColumnDisplaySize(1));
+      assertEquals(10, meta.getPrecision(1));
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE IntCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO IntCodec2(t1) VALUES (?)")) {
+      prep.setInt(1, 1);
+      prep.execute();
+      prep.setObject(1, 2);
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, 3, Types.INTEGER);
+      prep.execute();
+      prep.setObject(1, "4", Types.INTEGER);
+      prep.execute();
+      prep.setObject(1, null, Types.INTEGER);
+      prep.execute();
+      prep.setObject(1, 5, Types.VARCHAR);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM IntCodec2");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(2));
+    rs.updateInt("t1", 10);
+    rs.updateRow();
+    assertEquals(10, rs.getInt(2));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(2));
+    rs.updateObject(2, null);
+    rs.updateRow();
+    assertEquals(0, rs.getInt(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(2));
+    assertTrue(rs.wasNull());
+    rs.updateObject(2, 20);
+    rs.updateRow();
+    assertEquals(20, rs.getInt(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(3, rs.getInt(2));
+    rs.updateObject("t1", null, Types.INTEGER);
+    rs.updateRow();
+    assertEquals(0, rs.getInt(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(4, rs.getInt(2));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(2));
+    assertTrue(rs.wasNull());
+    rs.updateObject(2, 25, Types.INTEGER);
+    rs.updateRow();
+    assertEquals(25, rs.getInt(2));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.next());
+    assertEquals(5, rs.getInt(2));
+
+    rs = stmt.executeQuery("SELECT * FROM IntCodec2");
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(2));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(20, rs.getInt(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(4, rs.getInt(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(25, rs.getInt(2));
+    assertFalse(rs.wasNull());
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/LineStringCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/LineStringCodecTest.java
new file mode 100644
index 0000000..951bf36
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/LineStringCodecTest.java
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.type.GeometryCollection;
+import org.mariadb.jdbc.type.LineString;
+import org.mariadb.jdbc.type.Point;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class LineStringCodecTest extends CommonCodecTest {
+  public static org.mariadb.jdbc.Connection geoConn;
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS LineStringCodec");
+    stmt.execute("DROP TABLE IF EXISTS LineStringCodec2");
+    if (geoConn != null) geoConn.close();
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    // xpand doesn't recognized LineString
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE LineStringCodec (t1 LineString, t2 LineString, t3 LineString, t4"
+            + " LineString)");
+    stmt.execute(
+        "INSERT INTO LineStringCodec VALUES ( ST_LineStringFromText('LINESTRING(0 0,0 10,10 0)'),"
+            + " ST_LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)'),"
+            + " ST_LineStringFromText('LINESTRING(-1 0.55, 3 5, 1 1)'), null)");
+    stmt.execute(
+        "CREATE TABLE LineStringCodec2 (id int not null primary key auto_increment, t1"
+            + " LineString)");
+    stmt.execute("FLUSH TABLES");
+    String binUrl =
+        mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default";
+    geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl);
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " LineStringCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from LineStringCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get(), false);
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn), false);
+    getObject(getPrepare(sharedConnBinary), false);
+    getObject(getPrepare(geoConn), true);
+  }
+
+  public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException {
+    if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals(
+          new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true),
+          rs.getObject(1));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new LineString(
+              new Point[] {
+                new Point(10, 10),
+                new Point(20, 10),
+                new Point(20, 20),
+                new Point(10, 20),
+                new Point(10, 10)
+              },
+              true),
+          rs.getObject(2));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new LineString(new Point[] {new Point(-1, 0.55), new Point(3, 5), new Point(1, 1)}, true),
+          rs.getObject(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    } else {
+      assertEquals(
+          new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true),
+          rs.getObject(1, LineString.class));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new LineString(
+              new Point[] {
+                new Point(10, 10),
+                new Point(20, 10),
+                new Point(20, 20),
+                new Point(10, 20),
+                new Point(10, 10)
+              },
+              true),
+          rs.getObject(2, LineString.class));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new LineString(new Point[] {new Point(-1, 0.55), new Point(3, 5), new Point(1, 1)}, true),
+          rs.getObject(3, LineString.class));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testErrObject(rs, String.class);
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, GeometryCollection.class);
+    testErrObject(rs, Byte.class);
+    testArrObject(
+        rs,
+        new byte[] {
+          (byte) 0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x02,
+          0x00,
+          0x00,
+          0x00,
+          0x03,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x24,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x24,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00
+        });
+
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testErrObject(rs, java.util.Date.class);
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    getMetaData(sharedConn, false);
+    try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) {
+      getMetaData(con, true);
+    }
+  }
+
+  private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault)
+      throws SQLException {
+    ResultSet rs = getPrepare(con);
+    ResultSetMetaData meta = rs.getMetaData();
+    if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals("LINESTRING", meta.getColumnTypeName(1));
+    } else {
+      assertEquals("GEOMETRY", meta.getColumnTypeName(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+
+    assertEquals(
+        geoDefault
+            ? (hasCapability(Capabilities.EXTENDED_TYPE_INFO)
+                ? LineString.class.getName()
+                : GeometryCollection.class.getName())
+            : "byte[]",
+        meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE LineStringCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    LineString ls1 =
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true);
+    LineString ls2 =
+        new LineString(
+            new Point[] {
+              new Point(10, 10),
+              new Point(20, 10),
+              new Point(20, 20),
+              new Point(10, 20),
+              new Point(10, 10)
+            },
+            true);
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO LineStringCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, ls1);
+      prep.execute();
+      prep.setObject(1, (LineString) null);
+      prep.execute();
+
+      prep.setObject(1, ls2);
+      prep.addBatch();
+      prep.setObject(1, ls1);
+      prep.addBatch();
+      prep.executeBatch();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM LineStringCodec2");
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, LineString.class));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getObject(2, LineString.class));
+
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, LineString.class));
+    rs.updateObject(2, ls2);
+    rs.updateRow();
+    assertEquals(ls2, rs.getObject(2, LineString.class));
+    assertTrue(rs.next());
+
+    assertEquals(ls2, rs.getObject(2, LineString.class));
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, LineString.class));
+    con.commit();
+  }
+
+  @Test
+  public void equal() {
+    LineString ls =
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true);
+    assertTrue(ls.isOpen());
+    assertEquals(ls, ls);
+    assertEquals(
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true),
+        ls);
+    assertEquals(
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true)
+            .hashCode(),
+        ls.hashCode());
+    assertFalse(ls.equals(null));
+    assertFalse(ls.equals(""));
+    assertNotEquals(
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 20), new Point(20, 0)}, true),
+        ls);
+    assertNotEquals(
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, false),
+        ls);
+    assertNotEquals(
+        new LineString(
+            new Point[] {new Point(0, 0), new Point(0, 20), new Point(20, 10), new Point(10, 0)},
+            true),
+        ls);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/LongCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/LongCodecTest.java
new file mode 100644
index 0000000..6869b5f
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/LongCodecTest.java
@@ -0,0 +1,1070 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class LongCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS LongCodec");
+    stmt.execute("DROP TABLE IF EXISTS LongCodecUnsigned");
+    stmt.execute("DROP TABLE IF EXISTS LongCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE LongCodec (t1 BIGINT, t2 BIGINT, t3 BIGINT, t4 BIGINT)");
+    stmt.execute(
+        "CREATE TABLE LongCodecUnsigned (t1 BIGINT UNSIGNED, t2 BIGINT UNSIGNED, t3 BIGINT"
+            + " UNSIGNED, t4 BIGINT UNSIGNED)");
+    stmt.execute("INSERT INTO LongCodec VALUES (0, 1, -1, null)");
+    stmt.execute("INSERT INTO LongCodecUnsigned VALUES (0, 1, 18446744073709551615, null)");
+    stmt.execute("CREATE TABLE LongCodec2 (id int not null primary key auto_increment, t1 BIGINT)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet getSigned() throws SQLException {
+    return get("LongCodec");
+  }
+
+  private ResultSet getUnsigned() throws SQLException {
+    return get("LongCodecUnsigned");
+  }
+
+  private ResultSet getSignedPrepared(Connection con) throws SQLException {
+    return getPrepare(con, "LongCodec");
+  }
+
+  private ResultSet getUnsignedPrepared(Connection con) throws SQLException {
+    return getPrepare(con, "LongCodecUnsigned");
+  }
+
+  private ResultSet get(String table) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from " + table);
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con, String table) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from "
+                + table
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(getSigned());
+  }
+
+  @Test
+  public void getObjectPrepared() throws SQLException {
+    getObject(getSignedPrepared(sharedConn));
+    getObject(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getObject(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getObject(2));
+    assertEquals(1L, rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(getSigned());
+  }
+
+  @Test
+  public void getObjectTypePrepared() throws Exception {
+    getObjectType(getSignedPrepared(sharedConn));
+    getObjectType(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(getSigned());
+  }
+
+  @Test
+  public void getStringPrepared() throws SQLException {
+    getString(getSignedPrepared(sharedConn));
+    getString(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getStringUnsigned() throws SQLException {
+    getStringUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getStringUnsignedPrepared() throws SQLException {
+    getStringUnsigned(getUnsignedPrepared(sharedConn));
+    getStringUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getStringUnsigned(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("18446744073709551615", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(getSigned());
+  }
+
+  @Test
+  public void getNStringPrepared() throws SQLException {
+    getNString(getSignedPrepared(sharedConn));
+    getNString(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(getSigned());
+  }
+
+  @Test
+  public void getBooleanPrepared() throws SQLException {
+    getBoolean(getSignedPrepared(sharedConn));
+    getBoolean(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(getSigned());
+  }
+
+  @Test
+  public void getBytePrepared() throws SQLException {
+    getByte(getSignedPrepared(sharedConn));
+    getByte(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByteUnsigned() throws SQLException {
+    getByteUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getByteUnsignedPrepared() throws SQLException {
+    getByteUnsigned(getUnsignedPrepared(sharedConn));
+    getByteUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getByteUnsigned(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertThrows(SQLDataException.class, () -> rs.getByte(3));
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(getSigned());
+  }
+
+  @Test
+  public void getShortPrepared() throws SQLException {
+    getShort(getSignedPrepared(sharedConn));
+    getShort(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(getSigned());
+  }
+
+  @Test
+  public void getIntPrepared() throws SQLException {
+    getInt(getSignedPrepared(sharedConn));
+    getInt(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getIntUnsigned() throws SQLException {
+    getIntUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getIntUnsignedPrepared() throws SQLException {
+    getIntUnsigned(getUnsignedPrepared(sharedConn));
+    getIntUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getIntUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertFalse(rs.wasNull());
+    try {
+      rs.getInt(3);
+      fail();
+    } catch (SQLDataException e) {
+      assertTrue(
+          e.getMessage().contains("integer overflow")
+              || e.getMessage()
+                  .contains("value '18446744073709551615' cannot be decoded as Integer"));
+    }
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(getSigned());
+  }
+
+  @Test
+  public void getLongPrepared() throws SQLException {
+    getLong(getSignedPrepared(sharedConn));
+    getLong(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLongUnsigned() throws SQLException {
+    getLongUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getLongUnsignedPrepared() throws SQLException {
+    getLongUnsigned(getUnsignedPrepared(sharedConn));
+    getLongUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getLongUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    try {
+      rs.getLong(3);
+      fail();
+    } catch (SQLDataException e) {
+      assertTrue(
+          e.getMessage().contains("long overflow")
+              || e.getMessage().contains("value '18446744073709551615' cannot be decoded as Long"));
+    }
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(getSigned());
+  }
+
+  @Test
+  public void getFloatPrepared() throws SQLException {
+    getFloat(getSignedPrepared(sharedConn));
+    getFloat(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloatUnsigned() throws SQLException {
+    getFloatUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getFloatUnsignedPrepared() throws SQLException {
+    getFloatUnsigned(getUnsignedPrepared(sharedConn));
+    getFloatUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getFloatUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(18446744073709551615F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(getSigned());
+  }
+
+  @Test
+  public void getDoublePrepared() throws SQLException {
+    getDouble(getSignedPrepared(sharedConn));
+    getDouble(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDoubleUnsigned() throws SQLException {
+    getDoubleUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getDoubleUnsignedPrepared() throws SQLException {
+    getDoubleUnsigned(getUnsignedPrepared(sharedConn));
+    getDoubleUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getDoubleUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(18446744073709551615D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(getSigned());
+  }
+
+  @Test
+  public void getBigDecimalPrepared() throws SQLException {
+    getBigDecimal(getSignedPrepared(sharedConn));
+    getBigDecimal(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(-1), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimalUnsigned() throws SQLException {
+    getBigDecimalUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigDecimalUnsignedPrepared() throws SQLException {
+    getBigDecimalUnsigned(getUnsignedPrepared(sharedConn));
+    getBigDecimalUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigDecimalUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigDecimal("18446744073709551615"), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigInteger() throws SQLException {
+    getBigInteger(getSigned());
+  }
+
+  @Test
+  public void getBigIntegerPrepared() throws SQLException {
+    getBigInteger(getSignedPrepared(sharedConn));
+    getBigInteger(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigInteger(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertEquals(BigInteger.ZERO, rs.getBigInteger(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getBigInteger(2));
+    assertEquals(BigInteger.ONE, rs.getBigInteger("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(-1), rs.getBigInteger(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigInteger(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigIntegerUnsigned() throws SQLException {
+    getBigIntegerUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigIntegerUnsignedPrepared() throws SQLException {
+    getBigIntegerUnsigned(getUnsignedPrepared(sharedConn));
+    getBigIntegerUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigIntegerUnsigned(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertEquals(BigInteger.ZERO, rs.getBigInteger(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getBigInteger(2));
+    assertEquals(BigInteger.ONE, rs.getBigInteger("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(new BigInteger("18446744073709551615"), rs.getBigInteger(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigInteger(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(getSigned());
+  }
+
+  @Test
+  public void getDatePrepared() throws SQLException {
+    getDate(getSignedPrepared(sharedConn));
+    getDate(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type BIGINT cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type BIGINT cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(getSigned());
+  }
+
+  @Test
+  public void getTimePrepared() throws SQLException {
+    getTime(getSignedPrepared(sharedConn));
+    getTime(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type BIGINT cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type BIGINT cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(getSigned());
+  }
+
+  @Test
+  public void getTimestampPrepared() throws SQLException {
+    getTimestamp(getSignedPrepared(sharedConn));
+    getTimestamp(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type BIGINT cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type BIGINT cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(getSigned());
+  }
+
+  @Test
+  public void getAsciiStreamPrepared() throws SQLException {
+    getAsciiStream(getSignedPrepared(sharedConn));
+    getAsciiStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type BIGINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type BIGINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(getSigned());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepared() throws SQLException {
+    getUnicodeStream(getSignedPrepared(sharedConn));
+    getUnicodeStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  private void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type BIGINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type BIGINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(getSigned());
+  }
+
+  @Test
+  public void getBinaryStreamPrepared() throws SQLException {
+    getBinaryStream(getSignedPrepared(sharedConn));
+    getBinaryStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type BIGINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type BIGINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(getSigned());
+  }
+
+  @Test
+  public void getBytesPrepared() throws SQLException {
+    getBytes(getSignedPrepared(sharedConn));
+    getBytes(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type BIGINT cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type BIGINT cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getCharacterStreamPrepared() throws SQLException {
+    getCharacterStream(getSignedPrepared(sharedConn));
+    getCharacterStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type BIGINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type BIGINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepared() throws SQLException {
+    getNCharacterStream(getSignedPrepared(sharedConn));
+    getNCharacterStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type BIGINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type BIGINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws SQLException {
+    getRef(getSigned());
+  }
+
+  @Test
+  public void getRefPrepared() throws SQLException {
+    getRef(getSignedPrepared(sharedConn));
+    getRef(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getRef(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(getSigned());
+  }
+
+  @Test
+  public void getBlobPrepared() throws SQLException {
+    getBlob(getSignedPrepared(sharedConn));
+    getBlob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type BIGINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type BIGINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(getSigned());
+  }
+
+  @Test
+  public void getClobPrepared() throws SQLException {
+    getClob(getSignedPrepared(sharedConn));
+    getClob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type BIGINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type BIGINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(getSigned());
+  }
+
+  @Test
+  public void getNClobPrepared() throws SQLException {
+    getNClob(getSignedPrepared(sharedConn));
+    getNClob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getNClob(1), "Data type BIGINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type BIGINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getArray() throws SQLException {
+    getArray(getSigned());
+  }
+
+  @Test
+  public void getArrayPrepared() throws SQLException {
+    getArray(getSignedPrepared(sharedConn));
+    getArray(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getArray(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getArray(1), "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getArray("t1alias"),
+        "Method ResultSet.getArray not supported");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(getSigned());
+  }
+
+  @Test
+  public void getURLPrepared() throws SQLException {
+    getURL(getSignedPrepared(sharedConn));
+    getURL(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse '0' as URL");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse '0' as URL");
+  }
+
+  @Test
+  public void getSQLXML() throws SQLException {
+    getSQLXML(getSigned());
+  }
+
+  @Test
+  public void getSQLXMLPrepared() throws SQLException {
+    getSQLXML(getSignedPrepared(sharedConn));
+    getSQLXML(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getSQLXML(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getSQLXML(1), "Method ResultSet.getSQLXML not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getSQLXML("t1alias"),
+        "Method ResultSet.getSQLXML not supported");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = getSigned();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("BIGINT", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Long", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.BIGINT, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(20, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(20, meta.getColumnDisplaySize(1));
+
+    rs = getUnsigned();
+    meta = rs.getMetaData();
+    assertEquals("BIGINT UNSIGNED", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.math.BigInteger", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.BIGINT, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(20, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(20, meta.getColumnDisplaySize(1));
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE LongCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO LongCodec2(t1) VALUES (?)")) {
+      prep.setLong(1, 1L);
+      prep.execute();
+      prep.setObject(1, 2L);
+      prep.execute();
+      prep.setObject(1, BigInteger.TEN);
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, 3L, Types.BIGINT);
+      prep.execute();
+      prep.setObject(1, BigInteger.valueOf(4), Types.BIGINT);
+      prep.execute();
+      prep.setObject(1, null, Types.BIGINT);
+      prep.execute();
+    }
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM LongCodec2");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getLong(2));
+    rs.updateLong(2, 50L);
+    rs.updateRow();
+    assertEquals(50L, rs.getLong(2));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getLong(2));
+    rs.updateLong("t1", 60L);
+    rs.updateRow();
+    assertEquals(60L, rs.getLong(2));
+
+    assertTrue(rs.next());
+    assertEquals(10, rs.getLong(2));
+    rs.updateObject("t1", null);
+    rs.updateRow();
+    assertEquals(0L, rs.getLong(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getLong(2));
+    assertTrue(rs.wasNull());
+    rs.updateObject("t1", 70L);
+    rs.updateRow();
+    assertEquals(70L, rs.getLong(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(3, rs.getLong(2));
+    rs.updateObject("t1", null, Types.BIGINT);
+    rs.updateRow();
+    assertEquals(0L, rs.getLong(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(4, rs.getLong(2));
+    rs.updateObject(2, BigInteger.valueOf(80));
+    rs.updateRow();
+    assertEquals(80L, rs.getLong(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getLong(2));
+    assertTrue(rs.wasNull());
+    rs.updateObject("t1", BigInteger.valueOf(180), Types.BIGINT);
+    rs.updateRow();
+    assertEquals(180L, rs.getLong(2));
+    assertFalse(rs.wasNull());
+
+    rs = stmt.executeQuery("SELECT * FROM LongCodec2");
+    assertTrue(rs.next());
+    assertEquals(50L, rs.getLong(2));
+
+    assertTrue(rs.next());
+    assertEquals(60L, rs.getLong(2));
+
+    assertTrue(rs.next());
+    assertEquals(0L, rs.getLong(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(70L, rs.getLong(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0L, rs.getLong(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(80L, rs.getLong(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(180L, rs.getLong(2));
+    assertFalse(rs.wasNull());
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/MediumIntCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/MediumIntCodecTest.java
new file mode 100644
index 0000000..9f618eb
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/MediumIntCodecTest.java
@@ -0,0 +1,1017 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class MediumIntCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS MediumIntCodec");
+    stmt.execute("DROP TABLE IF EXISTS MediumIntCodec2");
+    stmt.execute("DROP TABLE IF EXISTS MediumIntCodec3");
+    stmt.execute("DROP TABLE IF EXISTS MediumIntCodecUnsigned");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE MediumIntCodec (t1 MEDIUMINT, t2 MEDIUMINT, t3 MEDIUMINT, t4 MEDIUMINT)");
+    stmt.execute(
+        "CREATE TABLE MediumIntCodecUnsigned (t1 MEDIUMINT UNSIGNED, t2 MEDIUMINT UNSIGNED, t3"
+            + " MEDIUMINT UNSIGNED, t4 MEDIUMINT UNSIGNED)");
+    stmt.execute("INSERT INTO MediumIntCodec VALUES (0, 1, -1, null)");
+    stmt.execute("INSERT INTO MediumIntCodecUnsigned VALUES (0, 1, 16777215, null)");
+    stmt.execute(
+        "CREATE TABLE MediumIntCodec2 (id int not null primary key auto_increment, t1 MEDIUMINT)");
+    stmt.execute(
+        "CREATE TABLE MediumIntCodec3 (id int not null, id2 int not null, t1 MEDIUMINT, PRIMARY KEY"
+            + " (id, id2))");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet getSigned() throws SQLException {
+    return get("MediumIntCodec");
+  }
+
+  private ResultSet getUnsigned() throws SQLException {
+    return get("MediumIntCodecUnsigned");
+  }
+
+  private ResultSet getSignedPrepared(Connection con) throws SQLException {
+    return getPrepare(con, "MediumIntCodec");
+  }
+
+  private ResultSet getUnsignedPrepared(Connection con) throws SQLException {
+    return getPrepare(con, "MediumIntCodecUnsigned");
+  }
+
+  private ResultSet get(String table) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from " + table);
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con, String table) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from "
+                + table
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(getSigned());
+  }
+
+  @Test
+  public void getObjectPrepared() throws SQLException {
+    getObject(getSignedPrepared(sharedConn));
+    getObject(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getObject(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getObject(2));
+    assertEquals(1, rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(getSigned());
+  }
+
+  @Test
+  public void getObjectTypePrepared() throws Exception {
+    getObjectType(getSignedPrepared(sharedConn));
+    getObjectType(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(getSigned());
+  }
+
+  @Test
+  public void getStringPrepared() throws SQLException {
+    getString(getSignedPrepared(sharedConn));
+    getString(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getStringUnsigned() throws SQLException {
+    getStringUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getStringUnsignedPrepared() throws SQLException {
+    getStringUnsigned(getUnsignedPrepared(sharedConn));
+    getStringUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getStringUnsigned(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("16777215", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(getSigned());
+  }
+
+  @Test
+  public void getNStringPrepared() throws SQLException {
+    getNString(getSignedPrepared(sharedConn));
+    getNString(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(getSigned());
+  }
+
+  @Test
+  public void getBooleanPrepared() throws SQLException {
+    getBoolean(getSignedPrepared(sharedConn));
+    getBoolean(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(getSigned());
+  }
+
+  @Test
+  public void getBytePrepared() throws SQLException {
+    getByte(getSignedPrepared(sharedConn));
+    getByte(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(getSigned());
+  }
+
+  @Test
+  public void getShortPrepared() throws SQLException {
+    getShort(getSignedPrepared(sharedConn));
+    getShort(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(getSigned());
+  }
+
+  @Test
+  public void getIntPrepared() throws SQLException {
+    getInt(getSignedPrepared(sharedConn));
+    getInt(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getIntUnsigned() throws SQLException {
+    getIntUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getIntUnsignedPrepared() throws SQLException {
+    getIntUnsigned(getUnsignedPrepared(sharedConn));
+    getIntUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getIntUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertFalse(rs.wasNull());
+    assertEquals(16777215, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(getSigned());
+  }
+
+  @Test
+  public void getLongPrepared() throws SQLException {
+    getLong(getSignedPrepared(sharedConn));
+    getLong(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLongUnsigned() throws SQLException {
+    getLongUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getLongUnsignedPrepared() throws SQLException {
+    getLongUnsigned(getUnsignedPrepared(sharedConn));
+    getLongUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getLongUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(16777215L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(getSigned());
+  }
+
+  @Test
+  public void getFloatPrepared() throws SQLException {
+    getFloat(getSignedPrepared(sharedConn));
+    getFloat(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloatUnsigned() throws SQLException {
+    getFloatUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getFloatUnsignedPrepared() throws SQLException {
+    getFloatUnsigned(getUnsignedPrepared(sharedConn));
+    getFloatUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getFloatUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(16777215F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(getSigned());
+  }
+
+  @Test
+  public void getDoublePrepared() throws SQLException {
+    getDouble(getSignedPrepared(sharedConn));
+    getDouble(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDoubleUnsigned() throws SQLException {
+    getDoubleUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getDoubleUnsignedPrepared() throws SQLException {
+    getDoubleUnsigned(getUnsignedPrepared(sharedConn));
+    getDoubleUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getDoubleUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(16777215D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(getSigned());
+  }
+
+  @Test
+  public void getBigDecimalPrepared() throws SQLException {
+    getBigDecimal(getSignedPrepared(sharedConn));
+    getBigDecimal(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(-1), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimalUnsigned() throws SQLException {
+    getBigDecimalUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigDecimalUnsignedPrepared() throws SQLException {
+    getBigDecimalUnsigned(getUnsignedPrepared(sharedConn));
+    getBigDecimalUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigDecimalUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(16777215L), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigInteger() throws SQLException {
+    getBigInteger(getSigned());
+  }
+
+  @Test
+  public void getBigIntegerPrepared() throws SQLException {
+    getBigInteger(getSignedPrepared(sharedConn));
+    getBigInteger(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigInteger(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertEquals(BigInteger.ZERO, rs.getBigInteger(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getBigInteger(2));
+    assertEquals(BigInteger.ONE, rs.getBigInteger("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(-1), rs.getBigInteger(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigInteger(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigIntegerUnsigned() throws SQLException {
+    getBigIntegerUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigIntegerUnsignedPrepared() throws SQLException {
+    getBigIntegerUnsigned(getUnsignedPrepared(sharedConn));
+    getBigIntegerUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigIntegerUnsigned(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertEquals(BigInteger.ZERO, rs.getBigInteger(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getBigInteger(2));
+    assertEquals(BigInteger.ONE, rs.getBigInteger("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(16777215L), rs.getBigInteger(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigInteger(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(getSigned());
+  }
+
+  @Test
+  public void getDatePrepared() throws SQLException {
+    getDate(getSignedPrepared(sharedConn));
+    getDate(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(1),
+        "Data type MEDIUMINT cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(getSigned());
+  }
+
+  @Test
+  public void getTimePrepared() throws SQLException {
+    getTime(getSignedPrepared(sharedConn));
+    getTime(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "Data type MEDIUMINT cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(getSigned());
+  }
+
+  @Test
+  public void getTimestampPrepared() throws SQLException {
+    getTimestamp(getSignedPrepared(sharedConn));
+    getTimestamp(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type MEDIUMINT cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(getSigned());
+  }
+
+  @Test
+  public void getAsciiStreamPrepared() throws SQLException {
+    getAsciiStream(getSignedPrepared(sharedConn));
+    getAsciiStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type MEDIUMINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(getSigned());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepared() throws SQLException {
+    getUnicodeStream(getSignedPrepared(sharedConn));
+    getUnicodeStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  private void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type MEDIUMINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(getSigned());
+  }
+
+  @Test
+  public void getBinaryStreamPrepared() throws SQLException {
+    getBinaryStream(getSignedPrepared(sharedConn));
+    getBinaryStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type MEDIUMINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(getSigned());
+  }
+
+  @Test
+  public void getBytesPrepared() throws SQLException {
+    getBytes(getSignedPrepared(sharedConn));
+    getBytes(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type MEDIUMINT cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getCharacterStreamPrepared() throws SQLException {
+    getCharacterStream(getSignedPrepared(sharedConn));
+    getCharacterStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type MEDIUMINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepared() throws SQLException {
+    getNCharacterStream(getSignedPrepared(sharedConn));
+    getNCharacterStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type MEDIUMINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type MEDIUMINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws SQLException {
+    getRef(getSigned());
+  }
+
+  @Test
+  public void getRefPrepared() throws SQLException {
+    getRef(getSignedPrepared(sharedConn));
+    getRef(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getRef(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(getSigned());
+  }
+
+  @Test
+  public void getBlobPrepared() throws SQLException {
+    getBlob(getSignedPrepared(sharedConn));
+    getBlob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type MEDIUMINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(getSigned());
+  }
+
+  @Test
+  public void getClobPrepared() throws SQLException {
+    getClob(getSignedPrepared(sharedConn));
+    getClob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob(1),
+        "Data type MEDIUMINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(getSigned());
+  }
+
+  @Test
+  public void getNClobPrepared() throws SQLException {
+    getNClob(getSignedPrepared(sharedConn));
+    getNClob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob(1),
+        "Data type MEDIUMINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type MEDIUMINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getArray() throws SQLException {
+    getArray(getSigned());
+  }
+
+  @Test
+  public void getArrayPrepared() throws SQLException {
+    getArray(getSignedPrepared(sharedConn));
+    getArray(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getArray(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getArray(1), "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getArray("t1alias"),
+        "Method ResultSet.getArray not supported");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(getSigned());
+  }
+
+  @Test
+  public void getURLPrepared() throws SQLException {
+    getURL(getSignedPrepared(sharedConn));
+    getURL(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse '0' as URL");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse '0' as URL");
+  }
+
+  @Test
+  public void getSQLXML() throws SQLException {
+    getSQLXML(getSigned());
+  }
+
+  @Test
+  public void getSQLXMLPrepared() throws SQLException {
+    getSQLXML(getSignedPrepared(sharedConn));
+    getSQLXML(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getSQLXML(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getSQLXML(1), "Method ResultSet.getSQLXML not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getSQLXML("t1alias"),
+        "Method ResultSet.getSQLXML not supported");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = getSigned();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("MEDIUMINT", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Integer", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.INTEGER, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(9, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(9, meta.getColumnDisplaySize(1));
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE MediumIntCodec3");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO MediumIntCodec3(id, id2, t1) VALUES (?,?,?)")) {
+      prep.setInt(1, 1);
+      prep.setInt(2, 1);
+      prep.setInt(3, 3);
+      prep.execute();
+      prep.setInt(1, 2);
+      prep.setInt(2, 1);
+      prep.setObject(3, 2);
+      prep.execute();
+      prep.setInt(1, 3);
+      prep.setInt(2, 1);
+      prep.setObject(3, null);
+      prep.execute();
+      prep.setInt(1, 4);
+      prep.setInt(2, 1);
+      prep.setObject(3, 3, Types.INTEGER);
+      prep.execute();
+      prep.setInt(1, 5);
+      prep.setInt(2, 1);
+      prep.setObject(3, null, Types.INTEGER);
+      prep.execute();
+    }
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM MediumIntCodec3");
+    assertTrue(rs.next());
+    assertEquals(3, rs.getInt(3));
+    rs.updateInt("t1", 10);
+    rs.updateRow();
+    assertEquals(10, rs.getInt(3));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(3));
+    rs.updateObject("t1", null);
+    rs.updateRow();
+    assertEquals(0, rs.getInt(3));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(3));
+    assertTrue(rs.wasNull());
+    rs.updateInt(3, 50);
+    rs.updateRow();
+    assertEquals(50, rs.getInt(3));
+
+    assertTrue(rs.next());
+    assertEquals(3, rs.getInt(3));
+    rs.updateObject(3, null, Types.INTEGER);
+    rs.updateRow();
+    assertEquals(0, rs.getInt(3));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(3));
+    assertTrue(rs.wasNull());
+    rs.updateObject(3, 85, Types.INTEGER);
+    rs.updateRow();
+    assertEquals(85, rs.getInt(3));
+    assertFalse(rs.wasNull());
+
+    rs = stmt.executeQuery("SELECT * FROM MediumIntCodec3");
+    assertTrue(rs.next());
+    assertEquals(10, rs.getInt(3));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(3));
+
+    assertTrue(rs.next());
+    assertEquals(50, rs.getInt(3));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getInt(3));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(85, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/MultiLineStringCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/MultiLineStringCodecTest.java
new file mode 100644
index 0000000..4c5633e
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/MultiLineStringCodecTest.java
@@ -0,0 +1,445 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.type.GeometryCollection;
+import org.mariadb.jdbc.type.LineString;
+import org.mariadb.jdbc.type.MultiLineString;
+import org.mariadb.jdbc.type.Point;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class MultiLineStringCodecTest extends CommonCodecTest {
+  public static org.mariadb.jdbc.Connection geoConn;
+  private final MultiLineString ls1 =
+      new MultiLineString(
+          new LineString[] {
+            new LineString(
+                new Point[] {
+                  new Point(1, 1),
+                  new Point(1, 5),
+                  new Point(4, 9),
+                  new Point(6, 9),
+                  new Point(9, 3),
+                  new Point(7, 2)
+                },
+                true)
+          });
+  private final MultiLineString ls2 =
+      new MultiLineString(
+          new LineString[] {
+            new LineString(
+                new Point[] {
+                  new Point(0, 0), new Point(50, 0), new Point(50, 50), new Point(0, 50)
+                },
+                true),
+            new LineString(
+                new Point[] {
+                  new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(10, 20)
+                },
+                true)
+          });
+
+  private final MultiLineString ls3 =
+      new MultiLineString(
+          new LineString[] {
+            new LineString(
+                new Point[] {
+                  new Point(0, 0), new Point(50, 0), new Point(50, 50), new Point(0, 50)
+                },
+                true)
+          });
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS MultiLineStringCodec");
+    stmt.execute("DROP TABLE IF EXISTS MultiLineStringCodec2");
+    if (geoConn != null) geoConn.close();
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    // xpand doesn't recognized MultiLineString
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE MultiLineStringCodec (t1 MultiLineString, t2 MultiLineString, t3"
+            + " MultiLineString, t4 MultiLineString)");
+    stmt.execute(
+        "INSERT INTO MultiLineStringCodec VALUES (ST_MLineFromText('MULTILINESTRING((1 1,1 5,4 9,6"
+            + " 9,9 3,7 2))'), ST_MLineFromText('MULTILINESTRING((0 0,50 0,50 50,0 50), (10 10,20"
+            + " 10,20 20,10 20))'), ST_MLineFromText('MULTILINESTRING((0 0,50 0,50 50,0 50))'),"
+            + " null)");
+    stmt.execute(
+        "CREATE TABLE MultiLineStringCodec2 (id int not null primary key auto_increment, t1"
+            + " MultiLineString)");
+    stmt.execute("FLUSH TABLES");
+
+    String binUrl =
+        mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default";
+    geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl);
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " MultiLineStringCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " MultiLineStringCodec WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get(), false);
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn), false);
+    getObject(getPrepare(sharedConnBinary), false);
+    getObject(getPrepare(geoConn), true);
+  }
+
+  public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException {
+    if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals(ls1, rs.getObject(1));
+      assertFalse(rs.wasNull());
+      assertEquals(ls2, rs.getObject(2));
+      assertFalse(rs.wasNull());
+      assertEquals(ls3, rs.getObject(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    } else {
+      assertEquals(ls1, rs.getObject(1, MultiLineString.class));
+      assertFalse(rs.wasNull());
+      // MultiLineString((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))
+      assertEquals(ls2, rs.getObject(2, MultiLineString.class));
+      assertFalse(rs.wasNull());
+      assertEquals(ls3, rs.getObject(3, MultiLineString.class));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testErrObject(rs, String.class);
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testArrObject(
+        rs,
+        new byte[] {
+          (byte) 0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x05,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x02,
+          0x00,
+          0x00,
+          0x00,
+          0x06,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x14,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x10,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x22,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x18,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x22,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x22,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x08,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x1C,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x40
+        });
+
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testErrObject(rs, java.util.Date.class);
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    getMetaData(sharedConn, false);
+    try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) {
+      getMetaData(con, true);
+    }
+  }
+
+  private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault)
+      throws SQLException {
+    ResultSet rs = getPrepare(con);
+    ResultSetMetaData meta = rs.getMetaData();
+    if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals("MULTILINESTRING", meta.getColumnTypeName(1));
+    } else {
+      assertEquals("GEOMETRY", meta.getColumnTypeName(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals(
+        geoDefault
+            ? (hasCapability(Capabilities.EXTENDED_TYPE_INFO)
+                ? MultiLineString.class.getName()
+                : GeometryCollection.class.getName())
+            : "byte[]",
+        meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE MultiLineStringCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO MultiLineStringCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, ls1);
+      prep.execute();
+      prep.setObject(1, (MultiLineString) null);
+      prep.execute();
+
+      prep.setObject(1, ls2);
+      prep.addBatch();
+      prep.setObject(1, ls1);
+      prep.addBatch();
+      prep.executeBatch();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM MultiLineStringCodec2");
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, MultiLineString.class));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getObject(2, MultiLineString.class));
+
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, MultiLineString.class));
+    rs.updateObject(2, ls2);
+    rs.updateRow();
+    assertEquals(ls2, rs.getObject(2, MultiLineString.class));
+    assertTrue(rs.next());
+
+    assertEquals(ls2, rs.getObject(2, MultiLineString.class));
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, MultiLineString.class));
+    con.commit();
+  }
+
+  @Test
+  public void equal() {
+    assertEquals(ls2, ls2);
+    assertEquals(
+        new MultiLineString(
+            new LineString[] {
+              new LineString(
+                  new Point[] {
+                    new Point(0, 0), new Point(50, 0), new Point(50, 50), new Point(0, 50)
+                  },
+                  true),
+              new LineString(
+                  new Point[] {
+                    new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(10, 20)
+                  },
+                  true)
+            }),
+        ls2);
+    assertEquals(
+        new MultiLineString(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(0, 0), new Point(50, 0), new Point(50, 50), new Point(0, 50)
+                      },
+                      true),
+                  new LineString(
+                      new Point[] {
+                        new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(10, 20)
+                      },
+                      true)
+                })
+            .hashCode(),
+        ls2.hashCode());
+    assertFalse(ls2.equals(null));
+    assertFalse(ls2.equals(""));
+    assertNotEquals(ls1, ls2);
+    assertNotEquals(
+        new MultiLineString(
+            new LineString[] {
+              new LineString(
+                  new Point[] {
+                    new Point(0, 0), new Point(50, 0), new Point(50, 50), new Point(0, 50)
+                  },
+                  true),
+              new LineString(
+                  new Point[] {
+                    new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(10, 20)
+                  },
+                  false)
+            }),
+        ls1);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/MultiPointCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/MultiPointCodecTest.java
new file mode 100644
index 0000000..c51e682
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/MultiPointCodecTest.java
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.type.GeometryCollection;
+import org.mariadb.jdbc.type.MultiPoint;
+import org.mariadb.jdbc.type.Point;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class MultiPointCodecTest extends CommonCodecTest {
+  public static org.mariadb.jdbc.Connection geoConn;
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS MultiPointCodec");
+    stmt.execute("DROP TABLE IF EXISTS MultiPointCodec2");
+    if (geoConn != null) geoConn.close();
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    // xpand doesn't recognized MultiPoint
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE MultiPointCodec (t1 MultiPoint, t2 MultiPoint, t3 MultiPoint, t4"
+            + " MultiPoint)");
+    stmt.execute(
+        "INSERT INTO MultiPointCodec VALUES (ST_MPointFromText('MULTIPOINT(0 0,0 10,10 0)'),"
+            + " ST_MPointFromText('MULTIPOINT(10 10,20 10,20 20,10 20,10 10)'),"
+            + " ST_MPointFromText('MULTIPOINT(-1 0.55, 3 5, 1 1)'), null)");
+    stmt.execute(
+        "CREATE TABLE MultiPointCodec2 (id int not null primary key auto_increment, t1"
+            + " MultiPoint)");
+    stmt.execute("FLUSH TABLES");
+
+    String binUrl =
+        mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default";
+    geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl);
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " MultiPointCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from MultiPointCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get(), false);
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn), false);
+    getObject(getPrepare(sharedConnBinary), false);
+    getObject(getPrepare(geoConn), true);
+  }
+
+  public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException {
+    if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals(
+          new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}),
+          rs.getObject(1));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new MultiPoint(
+              new Point[] {
+                new Point(10, 10),
+                new Point(20, 10),
+                new Point(20, 20),
+                new Point(10, 20),
+                new Point(10, 10)
+              }),
+          rs.getObject(2));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new MultiPoint(new Point[] {new Point(-1, 0.55), new Point(3, 5), new Point(1, 1)}),
+          rs.getObject(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    } else {
+      assertEquals(
+          new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}),
+          rs.getObject(1, MultiPoint.class));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new MultiPoint(
+              new Point[] {
+                new Point(10, 10),
+                new Point(20, 10),
+                new Point(20, 20),
+                new Point(10, 20),
+                new Point(10, 10)
+              }),
+          rs.getObject(2, MultiPoint.class));
+      assertFalse(rs.wasNull());
+      assertEquals(
+          new MultiPoint(new Point[] {new Point(-1, 0.55), new Point(3, 5), new Point(1, 1)}),
+          rs.getObject(3, MultiPoint.class));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testErrObject(rs, String.class);
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testArrObject(
+        rs,
+        new byte[] {
+          (byte) 0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x04,
+          0x00,
+          0x00,
+          0x00,
+          0x03,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x01,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x01,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x24,
+          0x40,
+          0x01,
+          0x01,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x24,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00
+        });
+
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testErrObject(rs, java.util.Date.class);
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    getMetaData(sharedConn, false);
+    try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) {
+      getMetaData(con, true);
+    }
+  }
+
+  private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault)
+      throws SQLException {
+    ResultSet rs = getPrepare(con);
+    ResultSetMetaData meta = rs.getMetaData();
+    if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals("MULTIPOINT", meta.getColumnTypeName(1));
+    } else {
+      assertEquals("GEOMETRY", meta.getColumnTypeName(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals(
+        geoDefault
+            ? (hasCapability(Capabilities.EXTENDED_TYPE_INFO)
+                ? MultiPoint.class.getName()
+                : GeometryCollection.class.getName())
+            : "byte[]",
+        meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE MultiPointCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    MultiPoint ls1 =
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)});
+    MultiPoint ls2 =
+        new MultiPoint(
+            new Point[] {
+              new Point(10, 10),
+              new Point(20, 10),
+              new Point(20, 20),
+              new Point(10, 20),
+              new Point(10, 10)
+            });
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO MultiPointCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, ls1);
+      prep.execute();
+      prep.setObject(1, (MultiPoint) null);
+      prep.execute();
+
+      prep.setObject(1, ls2);
+      prep.addBatch();
+      prep.setObject(1, ls1);
+      prep.addBatch();
+      prep.executeBatch();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM MultiPointCodec2");
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, MultiPoint.class));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getObject(2, MultiPoint.class));
+
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, MultiPoint.class));
+    rs.updateObject(2, ls2);
+    rs.updateRow();
+    assertEquals(ls2, rs.getObject(2, MultiPoint.class));
+    assertTrue(rs.next());
+
+    assertEquals(ls2, rs.getObject(2, MultiPoint.class));
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, MultiPoint.class));
+    con.commit();
+  }
+
+  @Test
+  public void equal() {
+    MultiPoint mp =
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)});
+    assertEquals(mp, mp);
+    assertEquals(
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}), mp);
+    assertEquals(
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)})
+            .hashCode(),
+        mp.hashCode());
+    assertFalse(mp.equals(null));
+    assertFalse(mp.equals(""));
+    assertNotEquals(
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 20)}), mp);
+    assertNotEquals(
+        new MultiPoint(
+            new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0), new Point(10, 20)}),
+        mp);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/MultiPolygonCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/MultiPolygonCodecTest.java
new file mode 100644
index 0000000..469dad2
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/MultiPolygonCodecTest.java
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.type.*;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class MultiPolygonCodecTest extends CommonCodecTest {
+  public static org.mariadb.jdbc.Connection geoConn;
+  private final MultiPolygon ls1 =
+      new MultiPolygon(
+          new Polygon[] {
+            new Polygon(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(1, 1),
+                        new Point(1, 5),
+                        new Point(4, 9),
+                        new Point(6, 9),
+                        new Point(9, 3),
+                        new Point(7, 2),
+                        new Point(1, 1)
+                      },
+                      false),
+                }),
+            new Polygon(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(0, 0),
+                        new Point(50, 0),
+                        new Point(50, 50),
+                        new Point(0, 50),
+                        new Point(0, 0)
+                      },
+                      false),
+                  new LineString(
+                      new Point[] {
+                        new Point(10, 10),
+                        new Point(20, 10),
+                        new Point(20, 20),
+                        new Point(10, 20),
+                        new Point(10, 10)
+                      },
+                      false)
+                })
+          });
+  private final MultiPolygon ls2 =
+      new MultiPolygon(
+          new Polygon[] {
+            new Polygon(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(1, 1),
+                        new Point(1, 8),
+                        new Point(4, 9),
+                        new Point(6, 9),
+                        new Point(9, 3),
+                        new Point(7, 2),
+                        new Point(1, 1)
+                      },
+                      false),
+                })
+          });
+
+  private final MultiPolygon ls3 =
+      new MultiPolygon(
+          new Polygon[] {
+            new Polygon(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(0, 0),
+                        new Point(50, 0),
+                        new Point(50, 50),
+                        new Point(0, 50),
+                        new Point(0, 0)
+                      },
+                      false),
+                  new LineString(
+                      new Point[] {
+                        new Point(10, 10),
+                        new Point(20, 10),
+                        new Point(20, 20),
+                        new Point(10, 20),
+                        new Point(10, 10)
+                      },
+                      false)
+                })
+          });
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS MultiPolygonCodec");
+    stmt.execute("DROP TABLE IF EXISTS MultiPolygonCodec2");
+    if (geoConn != null) geoConn.close();
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    // xpand doesn't recognized MultiPolygon
+    Assumptions.assumeFalse(isXpand());
+
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE MultiPolygonCodec (t1 MultiPolygon, t2 MultiPolygon, t3 MultiPolygon, t4"
+            + " MultiPolygon)");
+    stmt.execute(
+        "INSERT INTO MultiPolygonCodec VALUES (ST_MPolyFromText('MULTIPOLYGON(((1 1, 1 5,4 9,6 9,9"
+            + " 3,7 2, 1 1)), ((0 0, 50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10)))'),"
+            + " ST_MPolyFromText('MULTIPOLYGON(((1 1, 1 8,4 9,6 9,9 3,7 2, 1 1)))'),"
+            + " ST_MPolyFromText('MULTIPOLYGON(((0 0, 50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10"
+            + " 20,10 10)))'), null)");
+    stmt.execute(
+        "CREATE TABLE MultiPolygonCodec2 (id int not null primary key auto_increment, t1"
+            + " MultiPolygon)");
+    stmt.execute("FLUSH TABLES");
+
+    String binUrl =
+        mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default";
+    geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl);
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " MultiPolygonCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " MultiPolygonCodec WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get(), false);
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn), false);
+    getObject(getPrepare(sharedConnBinary), false);
+    getObject(getPrepare(geoConn), true);
+  }
+
+  public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException {
+    if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals(ls1, rs.getObject(1));
+      assertFalse(rs.wasNull());
+      assertEquals(ls2, rs.getObject(2));
+      assertFalse(rs.wasNull());
+      assertEquals(ls3, rs.getObject(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    } else {
+      assertEquals(ls1, rs.getObject(1, MultiPolygon.class));
+      assertFalse(rs.wasNull());
+      assertEquals(ls2, rs.getObject(2, MultiPolygon.class));
+      assertFalse(rs.wasNull());
+      assertEquals(ls3, rs.getObject(3, MultiPolygon.class));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  private static int toDigit(char hexChar) {
+    int digit = Character.digit(hexChar, 16);
+    if (digit == -1) {
+      throw new IllegalArgumentException("Invalid Hexadecimal Character: " + hexChar);
+    }
+    return digit;
+  }
+
+  public static byte hexToByte(String hexString) {
+    int firstDigit = toDigit(hexString.charAt(0));
+    int secondDigit = toDigit(hexString.charAt(1));
+    return (byte) ((firstDigit << 4) + secondDigit);
+  }
+
+  public static byte[] decodeHexString(String hexString) {
+    if (hexString.length() % 2 == 1) {
+      throw new IllegalArgumentException("Invalid hexadecimal String supplied.");
+    }
+
+    byte[] bytes = new byte[hexString.length() / 2];
+    for (int i = 0; i < hexString.length(); i += 2) {
+      bytes[i / 2] = hexToByte(hexString.substring(i, i + 2));
+    }
+    return bytes;
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class, 1);
+    testErrObject(rs, String.class, 1);
+    testErrObject(rs, Long.class, 1);
+    testErrObject(rs, Short.class, 1);
+    testErrObject(rs, BigDecimal.class, 1);
+    testErrObject(rs, BigInteger.class, 1);
+    testErrObject(rs, Double.class, 1);
+    testErrObject(rs, Float.class, 1);
+    testErrObject(rs, Byte.class, 1);
+    String hexa =
+        "0000000001060000000200000001030000000100000007000000000000000000F03F000000000000F03F000000000000F03F00000000000014400000000000001040000000000000224000000000000018400000000000002240000000000000224000000000000008400000000000001C400000000000000040000000000000F03F000000000000F03F010300000002000000050000000000000000000000000000000000000000000000000049400000000000000000000000000000494000000000000049400000000000000000000000000000494000000000000000000000000000000000050000000000000000002440000000000000244000000000000034400000000000002440000000000000344000000000000034400000000000002440000000000000344000000000000024400000000000002440";
+    testArrObject(rs, decodeHexString(hexa), 1);
+
+    testErrObject(rs, Boolean.class, 1);
+    testErrObject(rs, Clob.class, 1);
+    testErrObject(rs, NClob.class, 1);
+    testErrObject(rs, InputStream.class, 1);
+    testErrObject(rs, Reader.class, 1);
+    testErrObject(rs, java.util.Date.class, 1);
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    getMetaData(sharedConn, false);
+    try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) {
+      getMetaData(con, true);
+    }
+  }
+
+  private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault)
+      throws SQLException {
+    ResultSet rs = getPrepare(con);
+    ResultSetMetaData meta = rs.getMetaData();
+    if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals("MULTIPOLYGON", meta.getColumnTypeName(1));
+    } else {
+      assertEquals("GEOMETRY", meta.getColumnTypeName(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals(
+        geoDefault
+            ? (hasCapability(Capabilities.EXTENDED_TYPE_INFO)
+                ? MultiPolygon.class.getName()
+                : GeometryCollection.class.getName())
+            : "byte[]",
+        meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE MultiPolygonCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO MultiPolygonCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, ls1);
+      prep.execute();
+      prep.setObject(1, (MultiPolygon) null);
+      prep.execute();
+
+      prep.setObject(1, ls2);
+      prep.addBatch();
+      prep.setObject(1, ls1);
+      prep.addBatch();
+      prep.executeBatch();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM MultiPolygonCodec2");
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, MultiPolygon.class));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getObject(2, MultiPolygon.class));
+
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, MultiPolygon.class));
+    rs.updateObject(2, ls2);
+    rs.updateRow();
+    assertEquals(ls2, rs.getObject(2, MultiPolygon.class));
+    assertTrue(rs.next());
+
+    assertEquals(ls2, rs.getObject(2, MultiPolygon.class));
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, MultiPolygon.class));
+    con.commit();
+  }
+
+  @Test
+  public void equal() {
+    assertEquals(ls1, ls1);
+    MultiPolygon testPoly =
+        new MultiPolygon(
+            new Polygon[] {
+              new Polygon(
+                  new LineString[] {
+                    new LineString(
+                        new Point[] {
+                          new Point(1, 1),
+                          new Point(1, 5),
+                          new Point(4, 9),
+                          new Point(6, 9),
+                          new Point(9, 3),
+                          new Point(7, 2),
+                          new Point(1, 1)
+                        },
+                        false),
+                  }),
+              new Polygon(
+                  new LineString[] {
+                    new LineString(
+                        new Point[] {
+                          new Point(0, 0),
+                          new Point(50, 0),
+                          new Point(50, 50),
+                          new Point(0, 50),
+                          new Point(0, 0)
+                        },
+                        false),
+                    new LineString(
+                        new Point[] {
+                          new Point(10, 10),
+                          new Point(20, 10),
+                          new Point(20, 20),
+                          new Point(10, 20),
+                          new Point(10, 10)
+                        },
+                        false)
+                  })
+            });
+    assertEquals(testPoly, ls1);
+    assertEquals(testPoly.hashCode(), ls1.hashCode());
+    assertFalse(ls1.equals(null));
+    assertFalse(ls1.equals(""));
+    assertNotEquals(
+        new MultiPolygon(
+            new Polygon[] {
+              new Polygon(
+                  new LineString[] {
+                    new LineString(
+                        new Point[] {
+                          new Point(1, 1),
+                          new Point(1, 5),
+                          new Point(4, 9),
+                          new Point(6, 9),
+                          new Point(9, 3),
+                          new Point(7, 2),
+                          new Point(1, 1)
+                        },
+                        false),
+                  }),
+              new Polygon(
+                  new LineString[] {
+                    new LineString(
+                        new Point[] {
+                          new Point(0, 0),
+                          new Point(50, 0),
+                          new Point(50, 50),
+                          new Point(0, 50),
+                          new Point(0, 0)
+                        },
+                        false),
+                    new LineString(
+                        new Point[] {
+                          new Point(10, 10),
+                          new Point(20, 10),
+                          new Point(20, 20),
+                          new Point(10, 20),
+                          new Point(10, 15)
+                        },
+                        false)
+                  })
+            }),
+        ls1);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/NullCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/NullCodecTest.java
new file mode 100644
index 0000000..2bea3d8
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/NullCodecTest.java
@@ -0,0 +1,743 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class NullCodecTest extends CommonCodecTest {
+
+  private ResultSet getSigned() throws SQLException {
+    return get("IntCodec");
+  }
+
+  private ResultSet getUnsigned() throws SQLException {
+    return get("IntCodecUnsigned");
+  }
+
+  private ResultSet get(String table) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs = stmt.executeQuery("select NULL as t1alias");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPreparedSigned(Connection con) throws SQLException {
+    return getPrepare(con, "IntCodec");
+  }
+
+  private ResultSet getPreparedUnsigned(Connection con) throws SQLException {
+    return getPrepare(con, "IntCodecUnsigned");
+  }
+
+  private ResultSet getPrepare(Connection con, String table) throws SQLException {
+    Assumptions.assumeTrue(
+        (isMariaDBServer() && minVersion(10, 4, 0)) || (!isMariaDBServer() && minVersion(8, 0, 0)));
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement preparedStatement =
+        con.prepareStatement("select NULL as t1alias WHERE 1 > ?")) {
+      preparedStatement.setInt(1, 0);
+      ResultSet rs = preparedStatement.executeQuery();
+      assertTrue(rs.next());
+      return rs;
+    } finally {
+      con.commit();
+    }
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(getSigned());
+  }
+
+  @Test
+  public void getObjectPrepared() throws SQLException {
+    getObject(getPreparedSigned(sharedConn));
+    getObject(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getObject(ResultSet rs) throws SQLException {
+    assertNull(rs.getObject(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getObject("t1alias"));
+    assertTrue(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, int.class),
+        "Cannot return null for primitive int");
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(getSigned());
+  }
+
+  @Test
+  public void getObjectTypePrepared() throws Exception {
+    getObjectType(getPreparedSigned(sharedConn));
+    getObjectType(getPreparedSigned(sharedConnBinary));
+  }
+
+  void testNullObject(ResultSet rs, Class<?> objClass) throws Exception {
+    assertNull(rs.getObject(1, objClass));
+    assertNull(rs.getObject("t1alias", objClass));
+  }
+
+  private void getObjectType(ResultSet rs) throws Exception {
+    testNullObject(rs, Integer.class);
+    testNullObject(rs, String.class);
+    testNullObject(rs, Long.class);
+    testNullObject(rs, Short.class);
+    testNullObject(rs, BigDecimal.class);
+    testNullObject(rs, BigInteger.class);
+    testNullObject(rs, Double.class);
+    testNullObject(rs, Float.class);
+    testNullObject(rs, Byte.class);
+    testNullObject(rs, byte[].class);
+    testNullObject(rs, Date.class);
+    testNullObject(rs, Time.class);
+    testNullObject(rs, Timestamp.class);
+    testNullObject(rs, java.util.Date.class);
+    testNullObject(rs, LocalDate.class);
+    testNullObject(rs, ZonedDateTime.class);
+    testNullObject(rs, OffsetDateTime.class);
+    testNullObject(rs, LocalDateTime.class);
+    testNullObject(rs, OffsetTime.class);
+    testNullObject(rs, Boolean.class);
+    testNullObject(rs, Clob.class);
+    testNullObject(rs, NClob.class);
+    testNullObject(rs, InputStream.class);
+    testNullObject(rs, Reader.class);
+    rs.next();
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(getSigned());
+  }
+
+  @Test
+  public void getStringPrepared() throws SQLException {
+    getString(getPreparedSigned(sharedConn));
+    getString(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getString(ResultSet rs) throws SQLException {
+    assertNull(rs.getString(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getString("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getStringUnsigned() throws SQLException {
+    getStringUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getStringUnsignedPrepared() throws SQLException {
+    getStringUnsigned(getPreparedUnsigned(sharedConn));
+    getStringUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getStringUnsigned(ResultSet rs) throws SQLException {
+    assertNull(rs.getString(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getString("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(getSigned());
+  }
+
+  @Test
+  public void getNStringPrepared() throws SQLException {
+    getNString(getPreparedSigned(sharedConn));
+    getNString(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getNString(ResultSet rs) throws SQLException {
+    assertNull(rs.getNString(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getNString("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(getSigned());
+  }
+
+  @Test
+  public void getBooleanPrepared() throws SQLException {
+    getBoolean(getPreparedSigned(sharedConn));
+    getBoolean(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBoolean(ResultSet rs) throws SQLException {
+    assertEquals(false, rs.getBoolean(1));
+    assertTrue(rs.wasNull());
+    assertEquals(false, rs.getBoolean("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(getSigned());
+  }
+
+  @Test
+  public void getBytePrepared() throws SQLException {
+    getByte(getPreparedSigned(sharedConn));
+    getByte(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getByte(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getByte(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getByte("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnsignedByte() throws SQLException {
+    getUnsignedByte(getUnsigned());
+  }
+
+  @Test
+  public void getUnsignedBytePrepared() throws SQLException {
+    getUnsignedByte(getPreparedUnsigned(sharedConn));
+    getUnsignedByte(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getUnsignedByte(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getByte(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getByte("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(getSigned());
+  }
+
+  @Test
+  public void getShortPrepared() throws SQLException {
+    getShort(getPreparedSigned(sharedConn));
+    getShort(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getShort("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(getSigned());
+  }
+
+  @Test
+  public void getIntPrepared() throws SQLException {
+    getInt(getPreparedSigned(sharedConn));
+    getInt(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getInt("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getIntUnsigned() throws SQLException {
+    getIntUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getIntUnsignedPrepared() throws SQLException {
+    getIntUnsigned(getPreparedUnsigned(sharedConn));
+    getIntUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getIntUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getInt("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(getSigned());
+  }
+
+  @Test
+  public void getLongPrepared() throws SQLException {
+    getLong(getPreparedSigned(sharedConn));
+    getLong(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getLong(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getLong("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLongUnsigned() throws SQLException {
+    getLongUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getLongUnsignedPrepared() throws SQLException {
+    getLongUnsigned(getPreparedUnsigned(sharedConn));
+    getLongUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getLongUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getLong(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getLong("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(getSigned());
+  }
+
+  @Test
+  public void getFloatPrepared() throws SQLException {
+    getFloat(getPreparedSigned(sharedConn));
+    getFloat(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getFloat(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getFloat("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloatUnsigned() throws SQLException {
+    getFloatUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getFloatUnsignedPrepared() throws SQLException {
+    getFloatUnsigned(getPreparedUnsigned(sharedConn));
+    getFloatUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getFloatUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getFloat(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getFloat("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(getSigned());
+  }
+
+  @Test
+  public void getDoublePrepared() throws SQLException {
+    getDouble(getPreparedSigned(sharedConn));
+    getDouble(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getDouble(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getDouble("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDoubleUnsigned() throws SQLException {
+    getDoubleUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getDoubleUnsignedPrepared() throws SQLException {
+    getDoubleUnsigned(getPreparedUnsigned(sharedConn));
+    getDoubleUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getDoubleUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getDouble(1));
+    assertTrue(rs.wasNull());
+    assertEquals(0, rs.getDouble("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(getSigned());
+  }
+
+  @Test
+  public void getBigDecimalPrepared() throws SQLException {
+    getBigDecimal(getPreparedSigned(sharedConn));
+    getBigDecimal(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBigDecimal(ResultSet rs) throws SQLException {
+    assertNull(rs.getBigDecimal(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getBigDecimal("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimalUnsigned() throws SQLException {
+    getBigDecimalUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigDecimalUnsignedPrepared() throws SQLException {
+    getBigDecimalUnsigned(getPreparedUnsigned(sharedConn));
+    getBigDecimalUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getBigDecimalUnsigned(ResultSet rs) throws SQLException {
+    assertNull(rs.getBigDecimal(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getBigDecimal("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigInteger() throws SQLException {
+    getBigInteger(getSigned());
+  }
+
+  @Test
+  public void getBigIntegerPrepared() throws SQLException {
+    getBigInteger(getPreparedSigned(sharedConn));
+    getBigInteger(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBigInteger(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertNull(rs.getBigInteger(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getBigInteger("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigIntegerUnsigned() throws SQLException {
+    getBigIntegerUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigIntegerUnsignedPrepared() throws SQLException {
+    getBigIntegerUnsigned(getPreparedUnsigned(sharedConn));
+    getBigIntegerUnsigned(getPreparedUnsigned(sharedConnBinary));
+  }
+
+  private void getBigIntegerUnsigned(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertNull(rs.getBigInteger(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getBigInteger("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(getSigned());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPreparedSigned(sharedConn));
+    getDuration(getPreparedSigned(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) throws SQLException {
+    assertNull(rs.getObject(1, Duration.class));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getObject("t1alias", Duration.class));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(getSigned());
+  }
+
+  @Test
+  public void getDatePrepared() throws SQLException {
+    getDate(getPreparedSigned(sharedConn));
+    getDate(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getDate(ResultSet rs) throws SQLException {
+    assertNull(rs.getDate(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getDate("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(getSigned());
+  }
+
+  @Test
+  public void getTimePrepared() throws SQLException {
+    getTime(getPreparedSigned(sharedConn));
+    getTime(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getTime(ResultSet rs) throws SQLException {
+    assertNull(rs.getTime(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getTime("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(getSigned());
+  }
+
+  @Test
+  public void getTimestampPrepared() throws SQLException {
+    getTimestamp(getPreparedSigned(sharedConn));
+    getTimestamp(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getTimestamp(ResultSet rs) throws SQLException {
+    assertNull(rs.getTimestamp(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getTimestamp("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(getSigned());
+  }
+
+  @Test
+  public void getAsciiStreamPrepared() throws SQLException {
+    getAsciiStream(getPreparedSigned(sharedConn));
+    getAsciiStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getAsciiStream(ResultSet rs) throws SQLException {
+    assertNull(rs.getAsciiStream(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getAsciiStream("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(getSigned());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepared() throws SQLException {
+    getUnicodeStream(getPreparedSigned(sharedConn));
+    getUnicodeStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  private void getUnicodeStream(ResultSet rs) throws SQLException {
+    assertNull(rs.getUnicodeStream(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getUnicodeStream("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(getSigned());
+  }
+
+  @Test
+  public void getBinaryStreamPrepared() throws SQLException {
+    getBinaryStream(getPreparedSigned(sharedConn));
+    getBinaryStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBinaryStream(ResultSet rs) throws SQLException {
+    assertNull(rs.getBinaryStream(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getBinaryStream("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(getSigned());
+  }
+
+  @Test
+  public void getBytesPrepared() throws SQLException {
+    getBytes(getPreparedSigned(sharedConn));
+    getBytes(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBytes(ResultSet rs) throws SQLException {
+    assertNull(rs.getBytes(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getBytes("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getCharacterStreamPrepared() throws SQLException {
+    getCharacterStream(getPreparedSigned(sharedConn));
+    getCharacterStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getCharacterStream(ResultSet rs) throws SQLException {
+    assertNull(rs.getCharacterStream(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getCharacterStream("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepared() throws SQLException {
+    getNCharacterStream(getPreparedSigned(sharedConn));
+    getNCharacterStream(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getNCharacterStream(ResultSet rs) throws SQLException {
+    assertNull(rs.getNCharacterStream(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getNCharacterStream("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(getSigned());
+  }
+
+  @Test
+  public void getBlobPrepared() throws SQLException {
+    getBlob(getPreparedSigned(sharedConn));
+    getBlob(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getBlob(ResultSet rs) throws SQLException {
+    assertNull(rs.getCharacterStream(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getCharacterStream("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(getSigned());
+  }
+
+  @Test
+  public void getClobPrepared() throws SQLException {
+    getClob(getPreparedSigned(sharedConn));
+    getClob(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getClob(ResultSet rs) throws SQLException {
+    assertNull(rs.getClob(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getClob("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(getSigned());
+  }
+
+  @Test
+  public void getNClobPrepared() throws SQLException {
+    getNClob(getPreparedSigned(sharedConn));
+    getNClob(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getNClob(ResultSet rs) throws SQLException {
+    assertNull(rs.getNClob(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getNClob("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(getSigned());
+  }
+
+  @Test
+  public void getURLPrepared() throws SQLException {
+    getURL(getPreparedSigned(sharedConn));
+    getURL(getPreparedSigned(sharedConnBinary));
+  }
+
+  private void getURL(ResultSet rs) throws SQLException {
+    assertNull(rs.getURL(1));
+    assertTrue(rs.wasNull());
+    assertNull(rs.getURL("t1alias"));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = getSigned();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("NULL", meta.getColumnTypeName(1));
+    assertEquals("", meta.getCatalogName(1));
+    assertEquals("byte[]", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1alias", meta.getColumnName(1));
+    assertEquals(Types.NULL, meta.getColumnType(1));
+    assertEquals(1, meta.getColumnCount());
+    assertEquals(0, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(0, meta.getColumnDisplaySize(1));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/PointCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/PointCodecTest.java
new file mode 100644
index 0000000..f2f010e
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/PointCodecTest.java
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.type.GeometryCollection;
+import org.mariadb.jdbc.type.Point;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class PointCodecTest extends CommonCodecTest {
+  public static org.mariadb.jdbc.Connection geoConn;
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS PointCodec");
+    stmt.execute("DROP TABLE IF EXISTS PointCodec2");
+    if (geoConn != null) geoConn.close();
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    // xpand doesn't recognized POINT
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE PointCodec (t1 POINT, t2 POINT, t3 POINT, t4 POINT)");
+    stmt.execute(
+        "INSERT INTO PointCodec VALUES (ST_PointFromText('POINT(10 1)'),"
+            + " ST_PointFromText('POINT(1.5 18)'), ST_PointFromText('POINT(-1 0.55)'), null)");
+    stmt.execute("CREATE TABLE PointCodec2 (id int not null primary key auto_increment, t1 POINT)");
+    stmt.execute("FLUSH TABLES");
+
+    String binUrl =
+        mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default";
+    geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl);
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from PointCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from PointCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get(), false);
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn), false);
+    getObject(getPrepare(sharedConnBinary), false);
+    getObject(getPrepare(geoConn), true);
+  }
+
+  public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException {
+    if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals(new Point(10, 1), rs.getObject(1));
+      assertFalse(rs.wasNull());
+      assertEquals(new Point(1.5, 18), rs.getObject(2));
+      assertFalse(rs.wasNull());
+      assertEquals(new Point(-1, 0.55), rs.getObject(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    } else {
+      assertEquals(new Point(10, 1), rs.getObject(1, Point.class));
+      assertFalse(rs.wasNull());
+      assertEquals(new Point(1.5, 18), rs.getObject(2, Point.class));
+      assertFalse(rs.wasNull());
+      assertEquals(new Point(-1, 0.55), rs.getObject(3, Point.class));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4, Point.class));
+      assertTrue(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testErrObject(rs, String.class);
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testArrObject(
+        rs,
+        new byte[] {
+          (byte) 0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x01,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x24,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F
+        });
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testErrObject(rs, java.util.Date.class);
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    getMetaData(sharedConn, false);
+    try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) {
+      getMetaData(con, true);
+    }
+  }
+
+  private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault)
+      throws SQLException {
+    ResultSet rs = getPrepare(con);
+    ResultSetMetaData meta = rs.getMetaData();
+    if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals("POINT", meta.getColumnTypeName(1));
+    } else {
+      assertEquals("GEOMETRY", meta.getColumnTypeName(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals(
+        geoDefault
+            ? (hasCapability(Capabilities.EXTENDED_TYPE_INFO)
+                ? Point.class.getName()
+                : GeometryCollection.class.getName())
+            : "byte[]",
+        meta.getColumnClassName(1));
+
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE PointCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO PointCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, new Point(52.1, 12.8));
+      prep.execute();
+      prep.setObject(1, (Point) null);
+      prep.execute();
+
+      prep.setObject(1, new Point(2.2, 3.3));
+      prep.addBatch();
+      prep.setObject(1, new Point(2, 3));
+      prep.addBatch();
+      prep.executeBatch();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM PointCodec2");
+    assertTrue(rs.next());
+    assertEquals(new Point(52.1, 12.8), rs.getObject(2, Point.class));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getObject(2, Point.class));
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, Point.class));
+    rs.updateObject(2, new Point(1, 8));
+    rs.updateRow();
+    assertEquals(new Point(1, 8), rs.getObject(2, Point.class));
+
+    assertTrue(rs.next());
+    assertEquals(new Point(2.2, 3.3), rs.getObject(2, Point.class));
+    assertTrue(rs.next());
+    assertEquals(new Point(2, 3), rs.getObject(2, Point.class));
+    con.commit();
+  }
+
+  @Test
+  public void equal() {
+    Point pt = new Point(0, 10);
+    assertEquals(pt, pt);
+    assertEquals(new Point(0, 10), pt);
+    assertEquals(new Point(0, 10).hashCode(), pt.hashCode());
+    assertFalse(pt.equals(null));
+    assertFalse(pt.equals(""));
+    assertNotEquals(new Point(0, 20), pt);
+    assertNotEquals(new Point(10, 10), pt);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/PolygonCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/PolygonCodecTest.java
new file mode 100644
index 0000000..0fd1960
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/PolygonCodecTest.java
@@ -0,0 +1,464 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.type.GeometryCollection;
+import org.mariadb.jdbc.type.LineString;
+import org.mariadb.jdbc.type.Point;
+import org.mariadb.jdbc.type.Polygon;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class PolygonCodecTest extends CommonCodecTest {
+  public static org.mariadb.jdbc.Connection geoConn;
+  private final Polygon ls1 =
+      new Polygon(
+          new LineString[] {
+            new LineString(
+                new Point[] {
+                  new Point(1, 1),
+                  new Point(1, 5),
+                  new Point(4, 9),
+                  new Point(6, 9),
+                  new Point(9, 3),
+                  new Point(7, 2),
+                  new Point(1, 1)
+                },
+                false)
+          });
+  private final Polygon ls2 =
+      new Polygon(
+          new LineString[] {
+            new LineString(
+                new Point[] {
+                  new Point(0, 0),
+                  new Point(50, 0),
+                  new Point(50, 50),
+                  new Point(0, 50),
+                  new Point(0, 0)
+                },
+                false),
+            new LineString(
+                new Point[] {
+                  new Point(10, 10),
+                  new Point(20, 10),
+                  new Point(20, 20),
+                  new Point(10, 20),
+                  new Point(10, 10)
+                },
+                false)
+          });
+
+  private final Polygon ls3 =
+      new Polygon(
+          new LineString[] {
+            new LineString(
+                new Point[] {
+                  new Point(0, 0),
+                  new Point(50, 0),
+                  new Point(50, 50),
+                  new Point(0, 50),
+                  new Point(0, 0)
+                },
+                false)
+          });
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS PolygonCodec");
+    stmt.execute("DROP TABLE IF EXISTS PolygonCodec2");
+    if (geoConn != null) geoConn.close();
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws Exception {
+    drop();
+    // xpand doesn't recognized Polygon
+    Assumptions.assumeFalse(isXpand());
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE PolygonCodec (t1 Polygon, t2 Polygon, t3 Polygon, t4 Polygon)");
+    stmt.execute(
+        "INSERT INTO PolygonCodec VALUES (ST_PolygonFromText('POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1"
+            + " 1))'), ST_PolygonFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10"
+            + " 20,10 10))'), ST_PolygonFromText('POLYGON((0 0,50 0,50 50,0 50,0 0))'), null)");
+    stmt.execute(
+        "CREATE TABLE PolygonCodec2 (id int not null primary key auto_increment, t1 Polygon)");
+    stmt.execute("FLUSH TABLES");
+
+    String binUrl =
+        mDefUrl + (mDefUrl.indexOf("?") > 0 ? "&" : "?") + "geometryDefaultType=default";
+    geoConn = (org.mariadb.jdbc.Connection) DriverManager.getConnection(binUrl);
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from PolygonCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private CompleteResult getPrepare(org.mariadb.jdbc.Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from PolygonCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    CompleteResult rs = (CompleteResult) preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get(), false);
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn), false);
+    getObject(getPrepare(sharedConnBinary), false);
+    getObject(getPrepare(geoConn), true);
+  }
+
+  public void getObject(ResultSet rs, boolean defaultGeo) throws SQLException {
+    if (defaultGeo && hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals(ls1, rs.getObject(1));
+      assertFalse(rs.wasNull());
+      assertEquals(ls2, rs.getObject(2));
+      assertFalse(rs.wasNull());
+      assertEquals(ls3, rs.getObject(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    } else {
+      assertEquals(ls1, rs.getObject(1, Polygon.class));
+      assertFalse(rs.wasNull());
+      // Polygon((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))
+      assertEquals(ls2, rs.getObject(2, Polygon.class));
+      assertFalse(rs.wasNull());
+      assertEquals(ls3, rs.getObject(3, Polygon.class));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getObject(4));
+      assertTrue(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testErrObject(rs, String.class);
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testArrObject(
+        rs,
+        new byte[] {
+          (byte) 0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x03,
+          0x00,
+          0x00,
+          0x00,
+          0x01,
+          0x00,
+          0x00,
+          0x00,
+          0x07,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x14,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x10,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x22,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x18,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x22,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x22,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x08,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x1C,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x40,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0xF0,
+          0x3F
+        });
+
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testErrObject(rs, java.util.Date.class);
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    getMetaData(sharedConn, false);
+    try (org.mariadb.jdbc.Connection con = createCon("geometryDefaultType=default")) {
+      getMetaData(con, true);
+    }
+  }
+
+  private void getMetaData(org.mariadb.jdbc.Connection con, boolean geoDefault)
+      throws SQLException {
+    ResultSet rs = getPrepare(con);
+    ResultSetMetaData meta = rs.getMetaData();
+    if (hasCapability(Capabilities.EXTENDED_TYPE_INFO)) {
+      assertEquals("POLYGON", meta.getColumnTypeName(1));
+    } else {
+      assertEquals("GEOMETRY", meta.getColumnTypeName(1));
+    }
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals(
+        (geoDefault
+            ? (hasCapability(Capabilities.EXTENDED_TYPE_INFO)
+                ? Polygon.class.getName()
+                : GeometryCollection.class.getName())
+            : "byte[]"),
+        meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE PolygonCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO PolygonCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, ls1);
+      prep.execute();
+      prep.setObject(1, (Polygon) null);
+      prep.execute();
+
+      prep.setObject(1, ls2);
+      prep.addBatch();
+      prep.setObject(1, ls1);
+      prep.addBatch();
+      prep.executeBatch();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM PolygonCodec2");
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, Polygon.class));
+    rs.updateNull(2);
+    rs.updateRow();
+    assertNull(rs.getObject(2, Polygon.class));
+
+    assertTrue(rs.next());
+    assertNull(rs.getObject(2, Polygon.class));
+    rs.updateObject(2, ls2);
+    rs.updateRow();
+    assertEquals(ls2, rs.getObject(2, Polygon.class));
+    assertTrue(rs.next());
+
+    assertEquals(ls2, rs.getObject(2, Polygon.class));
+    assertTrue(rs.next());
+    assertEquals(ls1, rs.getObject(2, Polygon.class));
+    con.commit();
+  }
+
+  @Test
+  public void equal() {
+    assertEquals(ls2, ls2);
+    Polygon testPoly =
+        new Polygon(
+            new LineString[] {
+              new LineString(
+                  new Point[] {
+                    new Point(0, 0),
+                    new Point(50, 0),
+                    new Point(50, 50),
+                    new Point(0, 50),
+                    new Point(0, 0)
+                  },
+                  false),
+              new LineString(
+                  new Point[] {
+                    new Point(10, 10),
+                    new Point(20, 10),
+                    new Point(20, 20),
+                    new Point(10, 20),
+                    new Point(10, 10)
+                  },
+                  false)
+            });
+    assertEquals(testPoly, ls2);
+    assertEquals(testPoly.hashCode(), ls2.hashCode());
+    assertFalse(ls2.equals(null));
+    assertFalse(ls2.equals(""));
+    assertNotEquals(
+        new Polygon(
+            new LineString[] {
+              new LineString(
+                  new Point[] {
+                    new Point(0, 0),
+                    new Point(50, 0),
+                    new Point(50, 60),
+                    new Point(0, 50),
+                    new Point(0, 0)
+                  },
+                  false),
+              new LineString(
+                  new Point[] {
+                    new Point(10, 10),
+                    new Point(20, 10),
+                    new Point(20, 20),
+                    new Point(10, 20),
+                    new Point(10, 10)
+                  },
+                  false)
+            }),
+        ls2);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/SmallIntCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/SmallIntCodecTest.java
new file mode 100644
index 0000000..c5ca35a
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/SmallIntCodecTest.java
@@ -0,0 +1,1028 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class SmallIntCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS SmallIntCodec");
+    stmt.execute("DROP TABLE IF EXISTS SmallIntCodec2");
+    stmt.execute("DROP TABLE IF EXISTS SmallIntCodecUnsigned");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE SmallIntCodec (t1 SMALLINT, t2 SMALLINT, t3 SMALLINT, t4 SMALLINT)");
+    stmt.execute(
+        "CREATE TABLE SmallIntCodec2 (id int not null primary key auto_increment, t1 SMALLINT)");
+    stmt.execute(
+        "CREATE TABLE SmallIntCodecUnsigned (t1 SMALLINT UNSIGNED, t2 SMALLINT UNSIGNED, t3"
+            + " SMALLINT UNSIGNED, t4 SMALLINT UNSIGNED)");
+    stmt.execute("INSERT INTO SmallIntCodec VALUES (0, 1, -1, null)");
+    stmt.execute("INSERT INTO SmallIntCodecUnsigned VALUES (0, 1, 65535, null)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet getSigned() throws SQLException {
+    return get("SmallIntCodec");
+  }
+
+  private ResultSet getUnsigned() throws SQLException {
+    return get("SmallIntCodecUnsigned");
+  }
+
+  private ResultSet getSignedPrepared(Connection con) throws SQLException {
+    return getPrepare(con, "SmallIntCodec");
+  }
+
+  private ResultSet getUnsignedPrepared(Connection con) throws SQLException {
+    return getPrepare(con, "SmallIntCodecUnsigned");
+  }
+
+  private ResultSet get(String table) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from " + table);
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con, String table) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from "
+                + table
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(getSigned());
+  }
+
+  @Test
+  public void getObjectPrepared() throws SQLException {
+    getObject(getSignedPrepared(sharedConn));
+    getObject(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getObject(ResultSet rs) throws SQLException {
+    Object o = rs.getObject(1);
+    assertEquals(Short.valueOf("0"), rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals(Short.valueOf("1"), rs.getObject(2));
+    assertEquals(Short.valueOf("1"), rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(Short.valueOf("-1"), rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(getSigned());
+  }
+
+  @Test
+  public void getObjectTypePrepared() throws Exception {
+    getObjectType(getSignedPrepared(sharedConn));
+    getObjectType(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(getSigned());
+  }
+
+  @Test
+  public void getStringPrepared() throws SQLException {
+    getString(getSignedPrepared(sharedConn));
+    getString(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getStringUnsigned() throws SQLException {
+    getStringUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getStringUnsignedPrepared() throws SQLException {
+    getStringUnsigned(getUnsignedPrepared(sharedConn));
+    getStringUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getStringUnsigned(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("65535", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(getSigned());
+  }
+
+  @Test
+  public void getNStringPrepared() throws SQLException {
+    getNString(getSignedPrepared(sharedConn));
+    getNString(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(getSigned());
+  }
+
+  @Test
+  public void getBooleanPrepared() throws SQLException {
+    getBoolean(getSignedPrepared(sharedConn));
+    getBoolean(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(getSigned());
+  }
+
+  @Test
+  public void getBytePrepared() throws SQLException {
+    getByte(getSignedPrepared(sharedConn));
+    getByte(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(getSigned());
+  }
+
+  @Test
+  public void getShortPrepared() throws SQLException {
+    getShort(getSignedPrepared(sharedConn));
+    getShort(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(getSigned());
+  }
+
+  @Test
+  public void getIntPrepared() throws SQLException {
+    getInt(getSignedPrepared(sharedConn));
+    getInt(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getIntUnsigned() throws SQLException {
+    getIntUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getIntUnsignedPrepared() throws SQLException {
+    getIntUnsigned(getUnsignedPrepared(sharedConn));
+    getIntUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getIntUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertFalse(rs.wasNull());
+    assertEquals(65535, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(getSigned());
+  }
+
+  @Test
+  public void getLongPrepared() throws SQLException {
+    getLong(getSignedPrepared(sharedConn));
+    getLong(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLongUnsigned() throws SQLException {
+    getLongUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getLongUnsignedPrepared() throws SQLException {
+    getLongUnsigned(getUnsignedPrepared(sharedConn));
+    getLongUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getLongUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(65535L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(getSigned());
+  }
+
+  @Test
+  public void getFloatPrepared() throws SQLException {
+    getFloat(getSignedPrepared(sharedConn));
+    getFloat(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloatUnsigned() throws SQLException {
+    getFloatUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getFloatUnsignedPrepared() throws SQLException {
+    getFloatUnsigned(getUnsignedPrepared(sharedConn));
+    getFloatUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getFloatUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(65535F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(getSigned());
+  }
+
+  @Test
+  public void getDoublePrepared() throws SQLException {
+    getDouble(getSignedPrepared(sharedConn));
+    getDouble(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDoubleUnsigned() throws SQLException {
+    getDoubleUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getDoubleUnsignedPrepared() throws SQLException {
+    getDoubleUnsigned(getUnsignedPrepared(sharedConn));
+    getDoubleUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getDoubleUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(65535D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigInteger() throws SQLException {
+    getBigInteger(getSigned());
+  }
+
+  @Test
+  public void getBigIntegerPrepared() throws SQLException {
+    getBigInteger(getSignedPrepared(sharedConn));
+    getBigInteger(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigInteger(ResultSet rs) throws SQLException {
+    assertEquals(BigInteger.ZERO, rs.getObject(1, BigInteger.class));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getObject(2, BigInteger.class));
+    assertEquals(BigInteger.ONE, rs.getObject("t2alias", BigInteger.class));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(-1), rs.getObject(3, BigInteger.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, BigInteger.class));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigIntegerUnsigned() throws SQLException {
+    getBigIntegerUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigIntegerUnsignedPrepared() throws SQLException {
+    getBigIntegerUnsigned(getUnsignedPrepared(sharedConn));
+    getBigIntegerUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigIntegerUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(BigInteger.ZERO, rs.getObject(1, BigInteger.class));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getObject(2, BigInteger.class));
+    assertEquals(BigInteger.ONE, rs.getObject("t2alias", BigInteger.class));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(65535L), rs.getObject(3, BigInteger.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, BigInteger.class));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(getSigned());
+  }
+
+  @Test
+  public void getBigDecimalPrepared() throws SQLException {
+    getBigDecimal(getSignedPrepared(sharedConn));
+    getBigDecimal(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(-1), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimalUnsigned() throws SQLException {
+    getBigDecimalUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigDecimalUnsignedPrepared() throws SQLException {
+    getBigDecimalUnsigned(getUnsignedPrepared(sharedConn));
+    getBigDecimalUnsigned(getUnsignedPrepared(sharedConnBinary));
+  }
+
+  private void getBigDecimalUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(65535L), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(getSigned());
+  }
+
+  @Test
+  public void getDatePrepared() throws SQLException {
+    getDate(getSignedPrepared(sharedConn));
+    getDate(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(1),
+        "Data type SMALLINT cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type SMALLINT cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(getSigned());
+  }
+
+  @Test
+  public void getTimePrepared() throws SQLException {
+    getTime(getSignedPrepared(sharedConn));
+    getTime(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "Data type SMALLINT cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type SMALLINT cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(getSigned());
+  }
+
+  @Test
+  public void getTimestampPrepared() throws SQLException {
+    getTimestamp(getSignedPrepared(sharedConn));
+    getTimestamp(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type SMALLINT cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type SMALLINT cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(getSigned());
+  }
+
+  @Test
+  public void getAsciiStreamPrepared() throws SQLException {
+    getAsciiStream(getSignedPrepared(sharedConn));
+    getAsciiStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type SMALLINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type SMALLINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(getSigned());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepared() throws SQLException {
+    getUnicodeStream(getSignedPrepared(sharedConn));
+    getUnicodeStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  private void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type SMALLINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type SMALLINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(getSigned());
+  }
+
+  @Test
+  public void getBinaryStreamPrepared() throws SQLException {
+    getBinaryStream(getSignedPrepared(sharedConn));
+    getBinaryStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type SMALLINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type SMALLINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(getSigned());
+  }
+
+  @Test
+  public void getBytesPrepared() throws SQLException {
+    getBytes(getSignedPrepared(sharedConn));
+    getBytes(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type SMALLINT cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type SMALLINT cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getCharacterStreamPrepared() throws SQLException {
+    getCharacterStream(getSignedPrepared(sharedConn));
+    getCharacterStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type SMALLINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type SMALLINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepared() throws SQLException {
+    getNCharacterStream(getSignedPrepared(sharedConn));
+    getNCharacterStream(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type SMALLINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type SMALLINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws SQLException {
+    getRef(getSigned());
+  }
+
+  @Test
+  public void getRefPrepared() throws SQLException {
+    getRef(getSignedPrepared(sharedConn));
+    getRef(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getRef(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(getSigned());
+  }
+
+  @Test
+  public void getBlobPrepared() throws SQLException {
+    getBlob(getSignedPrepared(sharedConn));
+    getBlob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type SMALLINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type SMALLINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(getSigned());
+  }
+
+  @Test
+  public void getClobPrepared() throws SQLException {
+    getClob(getSignedPrepared(sharedConn));
+    getClob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob(1),
+        "Data type SMALLINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type SMALLINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(getSigned());
+  }
+
+  @Test
+  public void getNClobPrepared() throws SQLException {
+    getNClob(getSignedPrepared(sharedConn));
+    getNClob(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob(1),
+        "Data type SMALLINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type SMALLINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getArray() throws SQLException {
+    getArray(getSigned());
+  }
+
+  @Test
+  public void getArrayPrepared() throws SQLException {
+    getArray(getSignedPrepared(sharedConn));
+    getArray(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getArray(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getArray(1), "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getArray("t1alias"),
+        "Method ResultSet.getArray not supported");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(getSigned());
+  }
+
+  @Test
+  public void getURLPrepared() throws SQLException {
+    getURL(getSignedPrepared(sharedConn));
+    getURL(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse '0' as URL");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse '0' as URL");
+  }
+
+  @Test
+  public void getSQLXML() throws SQLException {
+    getSQLXML(getSigned());
+  }
+
+  @Test
+  public void getSQLXMLPrepared() throws SQLException {
+    getSQLXML(getSignedPrepared(sharedConn));
+    getSQLXML(getSignedPrepared(sharedConnBinary));
+  }
+
+  private void getSQLXML(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getSQLXML(1), "Method ResultSet.getSQLXML not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getSQLXML("t1alias"),
+        "Method ResultSet.getSQLXML not supported");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = getSigned();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("SMALLINT", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Short", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.SMALLINT, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(6, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(6, meta.getColumnDisplaySize(1));
+
+    rs = getUnsigned();
+    meta = rs.getMetaData();
+    assertEquals("SMALLINT UNSIGNED", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Integer", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.INTEGER, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+
+    // https://jira.mariadb.org/browse/XPT-276
+    if (!isXpand()) {
+      assertEquals(5, meta.getPrecision(1));
+      assertEquals(5, meta.getColumnDisplaySize(1));
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE SmallIntCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO SmallIntCodec2(t1) VALUES (?)")) {
+      prep.setShort(1, (short) 1);
+      prep.execute();
+      prep.setObject(1, 2);
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, 3, Types.SMALLINT);
+      prep.execute();
+      prep.setObject(1, "4", Types.SMALLINT);
+      prep.execute();
+      prep.setObject(1, null, Types.SMALLINT);
+      prep.execute();
+    }
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM SmallIntCodec2");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getShort(2));
+    rs.updateShort("t1", (short) 45);
+    rs.updateRow();
+    assertEquals((short) 45, rs.getShort(2));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getShort(2));
+    rs.updateObject("t1", (Short) null);
+    rs.updateRow();
+    assertEquals(0, rs.getShort(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getShort(2));
+    assertTrue(rs.wasNull());
+    rs.updateShort(2, (short) 55);
+    rs.updateRow();
+    assertEquals((short) 55, rs.getShort(2));
+
+    assertTrue(rs.next());
+    assertEquals(3, rs.getShort(2));
+    rs.updateObject(2, Short.valueOf("5"), Types.SMALLINT);
+    rs.updateRow();
+    assertEquals(5, rs.getShort(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(4, rs.getShort(2));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getShort(2));
+    assertTrue(rs.wasNull());
+    rs.updateObject(2, null, Types.SMALLINT);
+    rs.updateRow();
+    assertEquals(0, rs.getShort(2));
+    assertTrue(rs.wasNull());
+
+    rs = stmt.executeQuery("SELECT * FROM SmallIntCodec2");
+    assertTrue(rs.next());
+    assertEquals((short) 45, rs.getShort(2));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getShort(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals((short) 55, rs.getShort(2));
+
+    assertTrue(rs.next());
+    assertEquals(5, rs.getShort(2));
+    assertFalse(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(4, rs.getShort(2));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getShort(2));
+    assertTrue(rs.wasNull());
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/TimeCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/TimeCodecTest.java
new file mode 100644
index 0000000..85bd146
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/TimeCodecTest.java
@@ -0,0 +1,855 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class TimeCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS TimeCodec");
+    stmt.execute("DROP TABLE IF EXISTS TimeCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE TimeCodec (t1 TIME(3), t2 TIME(6), t3 TIME(6), t4 TIME)");
+    stmt.execute(
+        "CREATE TABLE TimeCodec2 (id int not null primary key auto_increment, t1 TIME(3))");
+    stmt.execute(
+        "INSERT INTO TimeCodec VALUES ('01:55:12', '01:55:13.234567', '-18:30:12.55', null), "
+            + "('-838:59:58.999', '838:59:58.999999', '00:00:00', '00:00:00')");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from TimeCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from TimeCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals(
+        6912000, rs.getTime(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("01:55:12").getTime(), rs.getTime(1).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        6913234, rs.getTime(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("01:55:13").getTime() + 234, rs.getTime(2).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("-18:-30:-12").getTime() - 550, rs.getTime(3).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getTime(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(Time.valueOf("00:00:00").getTime(), rs.getTime(3).getTime());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get(), true);
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn), true);
+    getObjectType(getPrepare(sharedConnBinary), false);
+  }
+
+  public void getObjectType(ResultSet rs, boolean text) throws Exception {
+    testErrObject(rs, Integer.class);
+    if (isXpand() && !text) {
+      testObject(rs, String.class, "01:55:12");
+    } else {
+      testObject(rs, String.class, "01:55:12.000");
+    }
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Boolean.class);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testErrObject(rs, LocalDate.class);
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("1970-01-01T01:55:12"));
+    testObject(rs, LocalTime.class, LocalTime.parse("01:55:12"));
+    testObject(rs, Time.class, Time.valueOf("01:55:12"));
+    testObject(rs, Timestamp.class, Timestamp.valueOf("1970-01-01 01:55:12"));
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("1970-01-01T01:55:12").atZone(ZoneId.systemDefault()));
+    testObject(rs, java.util.Date.class, Timestamp.valueOf("1970-01-01 01:55:12.0"));
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get(), true);
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn), true);
+    getString(getPrepare(sharedConnBinary), false);
+  }
+
+  public void getString(ResultSet rs, boolean text) throws SQLException {
+    if (isXpand() && !text) {
+      // https://jira.mariadb.org/browse/XPT-273
+      assertEquals("01:55:12", rs.getString(1));
+      assertFalse(rs.wasNull());
+      assertEquals("01:55:13.234567", rs.getString(2));
+      assertEquals("01:55:13.234567", rs.getString("t2alias"));
+      assertFalse(rs.wasNull());
+      assertEquals("-18:30:12.550000", rs.getString(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getNString(4));
+      assertTrue(rs.wasNull());
+      rs.next();
+      assertTrue(
+          "-838:59:58.999".equals(rs.getString(1)) || "-838:59:58.999000".equals(rs.getString(1)));
+      assertFalse(rs.wasNull());
+      assertEquals("838:59:58.999999", rs.getString(2));
+      assertEquals("838:59:58.999999", rs.getString("t2alias"));
+      assertFalse(rs.wasNull());
+      assertEquals("00:00:00", rs.getString(3));
+      assertEquals("00:00:00", rs.getString(4));
+      assertFalse(rs.wasNull());
+
+    } else {
+      assertEquals("01:55:12.000", rs.getString(1));
+      assertFalse(rs.wasNull());
+      assertEquals("01:55:13.234567", rs.getString(2));
+      assertEquals("01:55:13.234567", rs.getString("t2alias"));
+      assertFalse(rs.wasNull());
+      assertEquals("-18:30:12.550000", rs.getString(3));
+      assertFalse(rs.wasNull());
+      assertNull(rs.getNString(4));
+      assertTrue(rs.wasNull());
+      rs.next();
+      assertTrue(
+          "-838:59:58.999".equals(rs.getString(1)) || "-838:59:58.999000".equals(rs.getString(1)));
+      assertFalse(rs.wasNull());
+      assertEquals("838:59:58.999999", rs.getString(2));
+      assertEquals("838:59:58.999999", rs.getString("t2alias"));
+      assertFalse(rs.wasNull());
+      assertEquals("00:00:00.000000", rs.getString(3));
+      assertEquals("00:00:00", rs.getString(4));
+      assertFalse(rs.wasNull());
+    }
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get(), true);
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn), true);
+    getNString(getPrepare(sharedConnBinary), false);
+  }
+
+  public void getNString(ResultSet rs, boolean text) throws SQLException {
+    if (isXpand() && !text) {
+      assertEquals("01:55:12", rs.getNString(1));
+    } else {
+      assertEquals("01:55:12.000", rs.getNString(1));
+    }
+    assertFalse(rs.wasNull());
+    assertEquals("01:55:13.234567", rs.getNString(2));
+    assertEquals("01:55:13.234567", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-18:30:12.550000", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBoolean(1), "Data type TIME cannot be decoded as Boolean");
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getByte(1), "Data type TIME cannot be decoded as Byte");
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getShort(1), "Data type TIME cannot be decoded as Short");
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getInt(1), "Data type TIME cannot be decoded as Integer");
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getLong(1), "Data type TIME cannot be decoded as Long");
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getFloat(1), "Data type TIME cannot be decoded as Float");
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getDouble(1), "Data type TIME cannot be decoded as Double");
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBigDecimal(1),
+        "Data type TIME cannot be decoded as BigDecimal");
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getDate(1), "Data type TIME cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    assertEquals(
+        6912000, rs.getTime(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("01:55:12").getTime(), rs.getTime(1).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        6913234, rs.getTime(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("01:55:13").getTime() + 234, rs.getTime(2).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Time.valueOf("-18:-30:-12").getTime() - 550, rs.getTime(3).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getTime(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(get());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPrepare(sharedConn));
+    getDuration(getPrepare(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) throws SQLException {
+    assertEquals(Duration.parse("PT1H55M12S"), rs.getObject(1, Duration.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Duration.parse("PT1H55M13.234567S"), rs.getObject(2, Duration.class));
+    assertEquals(Duration.parse("PT1H55M13.234567S"), rs.getObject("t2alias", Duration.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Duration.parse("PT-18H-30M-12.55S"), rs.getObject(3, Duration.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, Duration.class));
+    assertTrue(rs.wasNull());
+
+    rs.next();
+    assertEquals(Duration.parse("PT-838H-59M-58.999S"), rs.getObject(1, Duration.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Duration.parse("PT838H59M58.999999S"), rs.getObject(2, Duration.class));
+    assertEquals(Duration.parse("PT838H59M58.999999S"), rs.getObject("t2alias", Duration.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Duration.parse("PT0S"), rs.getObject(3, Duration.class));
+    assertEquals(Duration.parse("PT0S"), rs.getObject(4, Duration.class));
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getLocalTime() throws SQLException {
+    getLocalTime(get());
+  }
+
+  @Test
+  public void getLocalTimePrepare() throws SQLException {
+    getLocalTime(getPrepare(sharedConn));
+    getLocalTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalTime(ResultSet rs) throws SQLException {
+    assertEquals(LocalTime.parse("01:55:12"), rs.getObject(1, LocalTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalTime.parse("01:55:13.234567"), rs.getObject(2, LocalTime.class));
+    assertEquals(LocalTime.parse("01:55:13.234567"), rs.getObject("t2alias", LocalTime.class));
+    assertFalse(rs.wasNull());
+    // Duration.parse("PT-18H-30M-12.55S")
+    assertEquals(LocalTime.parse("05:29:47.450"), rs.getObject(3, LocalTime.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, LocalTime.class));
+    assertTrue(rs.wasNull());
+
+    rs.next();
+    assertEquals(Duration.parse("PT-838H-59M-58.999S"), rs.getObject(1, Duration.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Duration.parse("PT838H59M58.999999S"), rs.getObject(2, Duration.class));
+    assertEquals(Duration.parse("PT838H59M58.999999S"), rs.getObject("t2alias", Duration.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Duration.parse("PT0S"), rs.getObject(3, Duration.class));
+    assertEquals(Duration.parse("PT0S"), rs.getObject(4, Duration.class));
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    assertEquals(Timestamp.valueOf("1970-01-01 01:55:12").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        6912000, rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("1970-01-01 01:55:12").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        6912000,
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        Timestamp.valueOf("1970-01-01 01:55:13.234567").getTime(), rs.getTimestamp(2).getTime());
+    assertEquals(
+        6913234, rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Timestamp.valueOf("1969-12-31 05:29:47.45"), rs.getTimestamp(3));
+    assertNull(rs.getTimestamp(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLocalDateTime() throws SQLException {
+    getLocalDateTime(get());
+  }
+
+  @Test
+  public void getLocalDateTimePrepare() throws SQLException {
+    getLocalDateTime(getPrepare(sharedConn));
+    getLocalDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDateTime(ResultSet rs) throws SQLException {
+    assertEquals(LocalDateTime.parse("1970-01-01T01:55:12"), rs.getObject(1, LocalDateTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        LocalDateTime.parse("1970-01-01T01:55:13.234567"), rs.getObject(2, LocalDateTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        LocalDateTime.parse("1969-12-31T05:29:47.45"), rs.getObject(3, LocalDateTime.class));
+    assertNull(rs.getObject(4, LocalDateTime.class));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInstant() throws SQLException {
+    getInstant(get());
+  }
+
+  @Test
+  public void getInstantPrepare() throws SQLException {
+    getInstant(getPrepare(sharedConn));
+    getInstant(getPrepare(sharedConnBinary));
+  }
+
+  public void getInstant(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("1970-01-01T01:55:12"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(1, Instant.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("1970-01-01T01:55:13.234567"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(2, Instant.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        ZonedDateTime.of(LocalDateTime.parse("1969-12-31T05:29:47.45"), ZoneId.systemDefault())
+            .toInstant(),
+        rs.getObject(3, Instant.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, Instant.class));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getOffsetDateTime() throws SQLException {
+    getOffsetDateTime(get());
+  }
+
+  @Test
+  public void getOffsetDateTimePrepare() throws SQLException {
+    getOffsetDateTime(getPrepare(sharedConn));
+    getOffsetDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getOffsetDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, OffsetDateTime.class),
+        "cannot be decoded as OffsetDateTime");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type TIME cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type TIME cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type TIME cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBytes(1), "Data type TIME cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type TIME cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type TIME cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBlob(1), "Data type TIME cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getClob(1), "Data type TIME cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getNClob(1), "Data type TIME cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("TIME", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.sql.Time", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.TIME, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(14, meta.getPrecision(1));
+    assertEquals("", meta.getSchemaName(1));
+
+    // https://jira.mariadb.org/browse/XPT-273
+    if (!isXpand()) {
+      assertEquals(3, meta.getScale(1));
+      assertEquals(14, meta.getColumnDisplaySize(1));
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE TimeCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    Time tt = Time.valueOf("01:55:12");
+    tt.setTime(tt.getTime() + 120);
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO TimeCodec2(t1) VALUES (?)")) {
+      prep.setTime(1, tt);
+      prep.execute();
+      prep.setTime(1, null);
+      prep.execute();
+      prep.setObject(1, new Time(Time.valueOf("01:55:13").getTime() + 234));
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, Time.valueOf("01:55:14"), Types.TIME);
+      prep.execute();
+      prep.setObject(1, null, Types.TIME);
+      prep.execute();
+      prep.setObject(1, Duration.parse("PT23H54M51.84001S"), Types.TIME);
+      prep.execute();
+      prep.setObject(1, Duration.parse("PT23H54M52S"), Types.TIME);
+      prep.execute();
+      prep.setObject(1, LocalTime.parse("05:29:47.450"), Types.TIME);
+      prep.execute();
+      prep.setObject(1, LocalTime.parse("05:29:57"), Types.TIME);
+      prep.execute();
+      prep.setObject(1, "05:29:58", Types.TIME);
+      prep.execute();
+    }
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM TimeCodec2");
+    assertTrue(rs.next());
+    assertEquals(tt.getTime(), rs.getTime(2).getTime());
+    rs.updateTime("t1", null);
+    rs.updateRow();
+    assertNull(rs.getTime(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getTime(2));
+    rs.updateTime("t1", tt);
+    rs.updateRow();
+    assertEquals(tt.getTime(), rs.getTime(2).getTime());
+
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("01:55:13").getTime() + 234, rs.getTime(2).getTime());
+    rs.updateObject(2, Time.valueOf("01:55:14"), JDBCType.TIME);
+    rs.updateRow();
+    assertEquals(Time.valueOf("01:55:14").getTime(), rs.getTime(2).getTime());
+
+    assertTrue(rs.next());
+    assertNull(rs.getTime(2));
+    rs.updateTime(2, tt);
+    rs.updateRow();
+    assertEquals(tt.getTime(), rs.getTime(2).getTime());
+
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("01:55:14").getTime(), rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertNull(rs.getTime(2));
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("23:54:52").getTime(), rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("05:29:47").getTime() + 450, rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("05:29:57").getTime(), rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("05:29:58").getTime(), rs.getTime(2).getTime());
+
+    rs = stmt.executeQuery("SELECT * FROM TimeCodec2");
+    assertTrue(rs.next());
+    assertNull(rs.getTime(2));
+
+    assertTrue(rs.next());
+    assertEquals(tt.getTime(), rs.getTime(2).getTime());
+
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("01:55:14").getTime(), rs.getTime(2).getTime());
+
+    assertTrue(rs.next());
+    assertEquals(tt.getTime(), rs.getTime(2).getTime());
+
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("01:55:14").getTime(), rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertNull(rs.getTime(2));
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("23:54:52").getTime(), rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("05:29:47").getTime() + 450, rs.getTime(2).getTime());
+    assertTrue(rs.next());
+    assertEquals(Time.valueOf("05:29:57").getTime(), rs.getTime(2).getTime());
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/TinyIntCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/TinyIntCodecTest.java
new file mode 100644
index 0000000..5a32c20
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/TinyIntCodecTest.java
@@ -0,0 +1,1090 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class TinyIntCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS TinyIntCodec");
+    stmt.execute("DROP TABLE IF EXISTS TinyIntCodec2");
+    stmt.execute("DROP TABLE IF EXISTS TinyIntCodecUnsigned");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE TinyIntCodec (t1 TINYINT, t2 TINYINT, t3 TINYINT, t4 TINYINT)");
+    stmt.execute(
+        "CREATE TABLE TinyIntCodec2 (id int not null primary key auto_increment, t1 TINYINT)");
+    stmt.execute(
+        "CREATE TABLE TinyIntCodecUnsigned (t1 TINYINT UNSIGNED, t2 TINYINT UNSIGNED, t3 TINYINT"
+            + " UNSIGNED, t4 TINYINT UNSIGNED)");
+    stmt.execute("INSERT INTO TinyIntCodec VALUES (0, 1, -1, null)");
+    stmt.execute("INSERT INTO TinyIntCodecUnsigned VALUES (0, 1, 255, null)");
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet getSigned() throws SQLException {
+    return get("TinyIntCodec");
+  }
+
+  private ResultSet getUnsigned() throws SQLException {
+    return get("TinyIntCodecUnsigned");
+  }
+
+  private ResultSet getPrepareSigned(Connection con) throws SQLException {
+    return getPrepare(con, "TinyIntCodec");
+  }
+
+  private ResultSet getPrepareUnsigned(Connection con) throws SQLException {
+    return getPrepare(con, "TinyIntCodecUnsigned");
+  }
+
+  private ResultSet get(String table) throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from " + table);
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con, String table) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from "
+                + table
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(getSigned());
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepareSigned(sharedConn));
+    getObject(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws Exception {
+    assertEquals(0, rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getObject(2));
+    assertEquals(1, rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectUnsigned() throws Exception {
+    getObjectUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getObjectUnsignedPrepare() throws Exception {
+    getObjectUnsigned(getPrepareUnsigned(sharedConn));
+    getObjectUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  public void getObjectUnsigned(ResultSet rs) throws Exception {
+    assertEquals(0, rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getObject(2));
+    assertEquals(1, rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(255, rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(getSigned());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepareSigned(sharedConn));
+    getObjectType(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testErrObject(rs, byte[].class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Timestamp.class);
+    testErrObject(rs, java.util.Date.class);
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+  }
+
+  @Test
+  public void getObjectTypeBoolean() throws Exception {
+    getObjectTypeBoolean(getSigned());
+  }
+
+  @Test
+  public void getObjectTypeBooleanPrepare() throws Exception {
+    getObjectTypeBoolean(getPrepareSigned(sharedConn));
+    getObjectTypeBoolean(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getObjectTypeBoolean(ResultSet rs) throws Exception {
+    assertEquals(Boolean.FALSE, rs.getObject(1, Boolean.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Boolean.TRUE, rs.getObject(2, Boolean.class));
+    assertEquals(Boolean.TRUE, rs.getObject("t2alias", Boolean.class));
+    assertFalse(rs.wasNull());
+    assertEquals(Boolean.TRUE, rs.getObject(3, Boolean.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, Boolean.class));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getString() throws Exception {
+    getString(getSigned());
+  }
+
+  @Test
+  public void getStringPrepare() throws Exception {
+    getString(getPrepareSigned(sharedConn));
+    getString(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws Exception {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getStringUnsigned() throws SQLException {
+    getStringUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getStringUnsignedPrepared() throws SQLException {
+    getStringUnsigned(getPrepareUnsigned(sharedConn));
+    getStringUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  private void getStringUnsigned(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("255", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws Exception {
+    getNString(getSigned());
+  }
+
+  @Test
+  public void getNStringPrepare() throws Exception {
+    getNString(getPrepareSigned(sharedConn));
+    getNString(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws Exception {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("-1", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws Exception {
+    getBoolean(getSigned());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws Exception {
+    getBoolean(getPrepareSigned(sharedConn));
+    getBoolean(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws Exception {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(getSigned());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepareSigned(sharedConn));
+    getByte(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) -1, rs.getByte(3));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(getSigned());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepareSigned(sharedConn));
+    getShort(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(getSigned());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepareSigned(sharedConn));
+    getInt(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getIntUnsigned() throws SQLException {
+    getIntUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getIntUnsignedPrepare() throws SQLException {
+    getIntUnsigned(getPrepareUnsigned(sharedConn));
+    getIntUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  public void getIntUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertFalse(rs.wasNull());
+    assertEquals(255, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(getSigned());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepareSigned(sharedConn));
+    getLong(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLongUnsigned() throws SQLException {
+    getLongUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getLongUnsignedPrepare() throws SQLException {
+    getLongUnsigned(getPrepareUnsigned(sharedConn));
+    getLongUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  public void getLongUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(255L, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(getSigned());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepareSigned(sharedConn));
+    getFloat(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloatUnsigned() throws SQLException {
+    getFloatUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getFloatUnsignedPrepare() throws SQLException {
+    getFloatUnsigned(getPrepareUnsigned(sharedConn));
+    getFloatUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  public void getFloatUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(255F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(getSigned());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepareSigned(sharedConn));
+    getDouble(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(-1D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDoubleUnsigned() throws SQLException {
+    getDoubleUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getDoubleUnsignedPrepare() throws SQLException {
+    getDoubleUnsigned(getPrepareUnsigned(sharedConn));
+    getDoubleUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  public void getDoubleUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(255D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(getSigned());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepareSigned(sharedConn));
+    getBigDecimal(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(-1), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimalUnsigned() throws SQLException {
+    getBigDecimalUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigDecimalUnsignedPrepare() throws SQLException {
+    getBigDecimalUnsigned(getPrepareUnsigned(sharedConn));
+    getBigDecimalUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  public void getBigDecimalUnsigned(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(255L), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigIntegerUnsigned() throws SQLException {
+    getBigIntegerUnsigned(getUnsigned());
+  }
+
+  @Test
+  public void getBigIntegerUnsignedPrepare() throws SQLException {
+    getBigIntegerUnsigned(getPrepareUnsigned(sharedConn));
+    getBigIntegerUnsigned(getPrepareUnsigned(sharedConnBinary));
+  }
+
+  public void getBigIntegerUnsigned(ResultSet res) throws SQLException {
+    CompleteResult rs = (CompleteResult) res;
+    assertEquals(BigInteger.ZERO, rs.getBigInteger(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.ONE, rs.getBigInteger(2));
+    assertEquals(BigInteger.ONE, rs.getBigInteger("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigInteger.valueOf(255L), rs.getBigInteger(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigInteger(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(getSigned());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepareSigned(sharedConn));
+    getDate(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type TINYINT cannot be decoded as Date");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate("t1alias"),
+        "Data type TINYINT cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(getSigned());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepareSigned(sharedConn));
+    getTime(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type TINYINT cannot be decoded as Time");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime("t1alias"),
+        "Data type TINYINT cannot be decoded as Time");
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(getSigned());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepareSigned(sharedConn));
+    getTimestamp(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp(1),
+        "Data type TINYINT cannot be decoded as Timestamp");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTimestamp("t1alias"),
+        "Data type TINYINT cannot be decoded as Timestamp");
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(getSigned());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepareSigned(sharedConn));
+    getAsciiStream(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type TINYINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getAsciiStream("t1alias"),
+        "Data type TINYINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(getSigned());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws SQLException {
+    getUnicodeStream(getPrepareSigned(sharedConn));
+    getUnicodeStream(getPrepareSigned(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type TINYINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getUnicodeStream("t1alias"),
+        "Data type TINYINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(getSigned());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws SQLException {
+    getBinaryStream(getPrepareSigned(sharedConn));
+    getBinaryStream(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type TINYINT cannot be decoded as Stream");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBinaryStream("t1alias"),
+        "Data type TINYINT cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(getSigned());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepareSigned(sharedConn));
+    getBytes(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes(1),
+        "Data type TINYINT cannot be decoded as byte[]");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBytes("t1alias"),
+        "Data type TINYINT cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws SQLException {
+    getCharacterStream(getPrepareSigned(sharedConn));
+    getCharacterStream(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type TINYINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type TINYINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(getSigned());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws SQLException {
+    getNCharacterStream(getPrepareSigned(sharedConn));
+    getNCharacterStream(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type TINYINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream("t2alias"),
+        "Data type TINYINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getRef() throws SQLException {
+    getRef(getSigned());
+  }
+
+  @Test
+  public void getRefPrepare() throws SQLException {
+    getRef(getPrepareSigned(sharedConn));
+    getRef(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getRef(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef(1), "Method ResultSet.getRef not supported");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getRef("t2alias"), "Method ResultSet.getRef not supported");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(getSigned());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepareSigned(sharedConn));
+    getBlob(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type TINYINT cannot be decoded as Reader");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getCharacterStream("t1alias"),
+        "Data type TINYINT cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(getSigned());
+  }
+
+  @Test
+  public void getClobPrepare() throws SQLException {
+    getClob(getPrepareSigned(sharedConn));
+    getClob(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getClob(1), "Data type TINYINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getClob("t1alias"),
+        "Data type TINYINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(getSigned());
+  }
+
+  @Test
+  public void getNClobPrepare() throws SQLException {
+    getNClob(getPrepareSigned(sharedConn));
+    getNClob(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob(1),
+        "Data type TINYINT cannot be decoded as Clob");
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNClob("t1alias"),
+        "Data type TINYINT cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getArray() throws SQLException {
+    getArray(getSigned());
+  }
+
+  @Test
+  public void getArrayPrepare() throws SQLException {
+    getArray(getPrepareSigned(sharedConn));
+    getArray(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getArray(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getArray(1), "Method ResultSet.getArray not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getArray("t1alias"),
+        "Method ResultSet.getArray not supported");
+  }
+
+  @Test
+  public void getURL() throws SQLException {
+    getURL(getSigned());
+  }
+
+  @Test
+  public void getURLPrepare() throws SQLException {
+    getURL(getPrepareSigned(sharedConn));
+    getURL(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getURL(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL(1), "Could not parse '0' as URL");
+    Common.assertThrowsContains(
+        SQLSyntaxErrorException.class, () -> rs.getURL("t1alias"), "Could not parse '0' as URL");
+  }
+
+  @Test
+  public void getSQLXML() throws SQLException {
+    getSQLXML(getSigned());
+  }
+
+  @Test
+  public void getSQLXMLPrepare() throws SQLException {
+    getSQLXML(getPrepareSigned(sharedConn));
+    getSQLXML(getPrepareSigned(sharedConnBinary));
+  }
+
+  public void getSQLXML(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getSQLXML(1), "Method ResultSet.getSQLXML not supported");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getSQLXML("t1alias"),
+        "Method ResultSet.getSQLXML not supported");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = getSigned();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("TINYINT", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Integer", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.TINYINT, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(4, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(4, meta.getColumnDisplaySize(1));
+
+    rs = getUnsigned();
+    meta = rs.getMetaData();
+    assertEquals("TINYINT UNSIGNED", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.Integer", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.SMALLINT, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    // https://jira.mariadb.org/browse/XPT-276
+    if (!isXpand()) {
+      assertEquals(3, meta.getPrecision(1));
+      assertEquals(3, meta.getColumnDisplaySize(1));
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE TinyIntCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO TinyIntCodec2(t1) VALUES (?)")) {
+      prep.setByte(1, (byte) 1);
+      prep.execute();
+      prep.setBoolean(1, true);
+      prep.execute();
+      prep.setBoolean(1, false);
+      prep.execute();
+      prep.setBoolean(1, true);
+      prep.execute();
+      prep.setBoolean(1, false);
+      prep.execute();
+      prep.setObject(1, Byte.valueOf("2"));
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, (byte) 3, Types.TINYINT);
+      prep.execute();
+      prep.setObject(1, "4", Types.TINYINT);
+      prep.execute();
+      prep.setObject(1, Byte.valueOf("4"), Types.TINYINT);
+      prep.execute();
+      prep.setObject(1, null, Types.TINYINT);
+      prep.execute();
+      prep.setObject(1, "true", Types.BOOLEAN);
+      prep.execute();
+      prep.setObject(1, "false", Types.BOOLEAN);
+      prep.execute();
+    }
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM TinyIntCodec2");
+    assertTrue(rs.next());
+    assertEquals(1, rs.getByte(2));
+    rs.updateByte("t1", (byte) 10);
+    rs.updateRow();
+    assertEquals((byte) 10, rs.getByte(2));
+
+    assertTrue(rs.next());
+    assertTrue(rs.getBoolean(2));
+    rs.updateBoolean("t1", false);
+    rs.updateRow();
+    assertFalse(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertFalse(rs.getBoolean(2));
+    rs.updateBoolean("t1", true);
+    rs.updateRow();
+    assertTrue(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertTrue(rs.getBoolean(2));
+    rs.updateBoolean(2, false);
+    rs.updateRow();
+    assertFalse(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertFalse(rs.getBoolean(2));
+    rs.updateBoolean(2, true);
+    rs.updateRow();
+    assertTrue(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertEquals(2, rs.getByte(2));
+    rs.updateObject(2, (Byte) null);
+    rs.updateRow();
+    assertEquals(0, rs.getByte(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getByte(2));
+    assertTrue(rs.wasNull());
+    rs.updateByte(2, (byte) 15);
+    rs.updateRow();
+    assertEquals((byte) 15, rs.getByte(2));
+
+    assertTrue(rs.next());
+    assertEquals(3, rs.getByte(2));
+    assertTrue(rs.next());
+    assertEquals(4, rs.getByte(2));
+    assertTrue(rs.next());
+    assertEquals(4, rs.getShort(2));
+    assertTrue(rs.next());
+    assertEquals(0, rs.getByte(2));
+    assertTrue(rs.wasNull());
+    assertTrue(rs.next());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.next());
+    assertFalse(rs.getBoolean(2));
+
+    rs = stmt.executeQuery("SELECT * FROM TinyIntCodec2");
+    assertTrue(rs.next());
+    assertEquals((byte) 10, rs.getByte(2));
+
+    assertTrue(rs.next());
+    assertFalse(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertTrue(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertFalse(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertTrue(rs.getBoolean(2));
+
+    assertTrue(rs.next());
+    assertEquals(0, rs.getByte(2));
+    assertTrue(rs.wasNull());
+
+    assertTrue(rs.next());
+    assertEquals((byte) 15, rs.getByte(2));
+
+    assertTrue(rs.next());
+    assertEquals(3, rs.getByte(2));
+    assertTrue(rs.next());
+    assertEquals(4, rs.getShort(2));
+    assertTrue(rs.next());
+    assertEquals(4, rs.getShort(2));
+    assertTrue(rs.next());
+    assertEquals(0, rs.getByte(2));
+    assertTrue(rs.wasNull());
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/UuidCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/UuidCodecTest.java
new file mode 100644
index 0000000..6fac7d8
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/UuidCodecTest.java
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import java.util.UUID;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+import org.mariadb.jdbc.util.constants.Capabilities;
+
+public class UuidCodecTest extends CommonCodecTest {
+
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS UuidCodec");
+    stmt.execute("DROP TABLE IF EXISTS UuidCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Assumptions.assumeTrue(
+        isMariaDBServer()
+            && minVersion(10, 7, 0)
+            && hasCapability(Capabilities.EXTENDED_TYPE_INFO));
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE UuidCodec (t1 UUID, t2 UUID, t3 UUID, t4 UUID)");
+    stmt.execute("CREATE TABLE UuidCodec2 (t1 UUID)");
+    stmt.execute(
+        "INSERT INTO UuidCodec VALUES ('123e4567-e89b-12d3-a456-426655440000',"
+            + " '93aac041-1a14-11ec-ab4e-f859713e4be4', 'ffffffff-ffff-ffff-ffff-fffffffffffe',"
+            + " null)");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    stmt.closeOnCompletion();
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from UuidCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getAdd(String additional) throws SQLException {
+    try (Connection con = createCon(additional)) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+      stmt.closeOnCompletion();
+      ResultSet rs =
+          stmt.executeQuery(
+              "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from UuidCodec");
+      assertTrue(rs.next());
+      con.commit();
+      return rs;
+    }
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from UuidCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+    try (Connection con = createCon("&uuidAsString=1")) {
+      getObjectString(getPrepare(con));
+    }
+  }
+
+  public void getObject(ResultSet rs) throws Exception {
+    assertEquals(UUID.fromString("123e4567-e89b-12d3-a456-426655440000"), rs.getObject(1));
+    assertFalse(rs.wasNull());
+
+    assertEquals(UUID.fromString("93aac041-1a14-11ec-ab4e-f859713e4be4"), rs.getObject(2));
+    assertEquals(UUID.fromString("93aac041-1a14-11ec-ab4e-f859713e4be4"), rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertEquals(
+        UUID.fromString("ffffffff-ffff-ffff-ffff-fffffffffffe"), rs.getObject(3, UUID.class));
+    assertEquals(UUID.class, rs.getObject(3, UUID.class).getClass());
+  }
+
+  public void getObjectString(ResultSet rs) throws Exception {
+    assertEquals("123e4567-e89b-12d3-a456-426655440000", rs.getObject(1));
+    assertFalse(rs.wasNull());
+
+    assertEquals("93aac041-1a14-11ec-ab4e-f859713e4be4", rs.getObject(2));
+    assertEquals("93aac041-1a14-11ec-ab4e-f859713e4be4", rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertEquals("ffffffff-ffff-ffff-ffff-fffffffffffe", rs.getObject(3));
+    assertEquals(UUID.class, rs.getObject(3, UUID.class).getClass());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testErrObject(rs, Integer.class);
+    testObject(rs, String.class, "123e4567-e89b-12d3-a456-426655440000");
+    testErrObject(rs, Long.class);
+    testErrObject(rs, Short.class);
+    testErrObject(rs, BigDecimal.class);
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, Double.class);
+    testErrObject(rs, Float.class);
+    testErrObject(rs, Byte.class);
+    testObject(rs, Reader.class, new StringReader("123e4567-e89b-12d3-a456-426655440000"));
+    testErrObject(rs, LocalDate.class);
+    testErrObject(rs, LocalDateTime.class);
+    testErrObject(rs, LocalTime.class);
+    testErrObject(rs, Time.class);
+    testErrObject(rs, Date.class);
+    testErrObject(rs, ZonedDateTime.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testErrObject(rs, java.util.Date.class);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+    try (Connection con = createCon("&uuidAsString=1")) {
+      getString(getPrepare(con));
+    }
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("123e4567-e89b-12d3-a456-426655440000", rs.getObject(1, String.class));
+    assertFalse(rs.wasNull());
+
+    assertEquals("93aac041-1a14-11ec-ab4e-f859713e4be4", rs.getString(2));
+    assertEquals("93aac041-1a14-11ec-ab4e-f859713e4be4", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertEquals("ffffffff-ffff-ffff-ffff-fffffffffffe", rs.getString(3));
+    assertEquals(String.class, rs.getString(3).getClass());
+  }
+
+  @Test
+  public void getUuid() throws SQLException {
+    getUuid(get());
+  }
+
+  @Test
+  public void getUuidPrepare() throws SQLException {
+    getUuid(getPrepare(sharedConn));
+    getUuid(getPrepare(sharedConnBinary));
+  }
+
+  public void getUuid(ResultSet rs) throws SQLException {
+    assertEquals(
+        UUID.fromString("123e4567-e89b-12d3-a456-426655440000"), rs.getObject(1, UUID.class));
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        UUID.fromString("93aac041-1a14-11ec-ab4e-f859713e4be4"), rs.getObject(2, UUID.class));
+    assertEquals(
+        UUID.fromString("93aac041-1a14-11ec-ab4e-f859713e4be4"),
+        rs.getObject("t2alias", UUID.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, UUID.class));
+    assertEquals(
+        UUID.fromString("ffffffff-ffff-ffff-ffff-fffffffffffe"), rs.getObject(3, UUID.class));
+    assertEquals(UUID.class, rs.getObject(3, UUID.class).getClass());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(1), "Data type UUID cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getLong(1), "Data type UUID cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(1), "Data type UUID cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(1),
+        "Data type UUID cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(1),
+        "value '123e4567-e89b-12d3-a456-426655440000' cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getDate(1), "Data type UUID cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getTime(1), "Data type UUID cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("uuid", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.util.UUID", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.OTHER, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(36, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(36, meta.getColumnDisplaySize(1));
+
+    rs = getAdd("&uuidAsString=True");
+    meta = rs.getMetaData();
+    assertEquals("uuid", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.String", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.CHAR, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(36, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(36, meta.getColumnDisplaySize(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE UuidCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep = con.prepareStatement("INSERT INTO UuidCodec2(t1) VALUES (?)")) {
+      prep.setObject(1, UUID.fromString("123e4567-e89b-12d3-a456-426655440000"));
+      prep.execute();
+      prep.setString(1, "123e4568-e89b-12d3-a456-426655440000");
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM UuidCodec2");
+
+    assertTrue(rs.next());
+    assertEquals("123e4567-e89b-12d3-a456-426655440000", rs.getString(1));
+
+    assertTrue(rs.next());
+    assertEquals("123e4568-e89b-12d3-a456-426655440000", rs.getString(1));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(1));
+
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/VarbinaryCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/VarbinaryCodecTest.java
new file mode 100644
index 0000000..e7ec858
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/VarbinaryCodecTest.java
@@ -0,0 +1,771 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbBlob;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class VarbinaryCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS VarbinaryCodec");
+    stmt.execute("DROP TABLE IF EXISTS VarbinaryCodec2");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE VarbinaryCodec (t1 VARBINARY(20), t2 VARBINARY(30), t3 VARBINARY(20), t4"
+            + " VARBINARY(20))");
+    stmt.execute("CREATE TABLE VarbinaryCodec2 (t1 VARBINARY(20))");
+    stmt.execute(
+        "INSERT INTO VarbinaryCodec VALUES ('0', '1', 'some🌟', null), ('2011-01-01', '2010-12-31"
+            + " 23:59:59.152', '23:54:51.840010', null)");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    stmt.closeOnCompletion();
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from"
+                + " VarbinaryCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from VarbinaryCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws Exception {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws Exception {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws Exception {
+    assertArrayEquals("0".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(2));
+    assertArrayEquals("1".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), (byte[]) rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBlob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testArrObject(rs, new byte[] {(byte) '0'});
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testObject(rs, Clob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, NClob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, InputStream.class, new MariaDbClob("0".getBytes()).getBinaryStream());
+    testObject(rs, Reader.class, new StringReader("0"));
+    rs.next();
+    testObject(rs, LocalDate.class, LocalDate.parse("2011-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2011-01-01T00:00"));
+    testObject(rs, LocalTime.class, LocalTime.parse("23:54:51.840010"), 3);
+    Time t = Time.valueOf("23:54:51");
+    testObject(rs, Time.class, new Time(t.getTime() + 840), 3);
+    testObject(rs, Date.class, Date.valueOf("2011-01-01"));
+    Timestamp tt = Timestamp.valueOf("2010-12-31 23:59:59");
+    testObject(rs, Timestamp.class, new Timestamp(tt.getTime() + 152), 2);
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2011-01-01T00:00").atZone(ZoneId.systemDefault()));
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-12-31"), 2);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getByte(3),
+        "value 'some\uD83C\uDF1F' (VARSTRING) cannot be decoded as Byte");
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getShort(3), "value 'some🌟' cannot be decoded as Short");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(3), "value 'some🌟' cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getLong(3),
+        "value 'some\uD83C\uDF1F' cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(3), "value 'some🌟' cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(3),
+        "value 'some🌟' cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(3),
+        "value 'some🌟' cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(1),
+        "value '0' (VARSTRING) cannot be decoded as Date");
+    rs.next();
+    assertEquals("2011-01-01", rs.getDate(1).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate(2).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate("t2alias").toString());
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(3),
+        "value '23:54:51.840010' (VARSTRING) cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "VARSTRING value '2011-01-01' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(2),
+        "VARSTRING value '2010-12-31 23:59:59.152' cannot be decoded as Time");
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(3).getTime());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime("t3alias").getTime());
+    Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+    assertEquals(86091840, rs.getTime(3, utc).getTime());
+    assertEquals(86091840, rs.getTime("t3alias", utc).getTime());
+
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    rs.next();
+    assertEquals(Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152, rs.getTimestamp(2).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152,
+        rs.getTimestamp("t2alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t2alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    //
+    //    ('2011-01-01', '2010-12-31 23:59:59.152',"
+    //            + " '23:54:51.840010', null)
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getAsciiStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getAsciiStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getAsciiStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getUnicodeStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)),
+        rs.getUnicodeStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getUnicodeStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecated")
+  public void getBinaryStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getBinaryStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBinaryStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBinaryStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws Exception {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws Exception {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecated")
+  public void getBytes(ResultSet rs) throws Exception {
+    assertArrayEquals("0".getBytes(), rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(), rs.getBytes(2));
+    assertArrayEquals("1".getBytes(), rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBytes(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getNCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getNCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbBlob("0".getBytes()), rs.getBlob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), rs.getBlob(2));
+    assertStreamEquals(new MariaDbBlob("1".getBytes()), rs.getBlob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbBlob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBlob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBlob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getNClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getNClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("VARBINARY", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("byte[]", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARBINARY, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(20, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(20, meta.getColumnDisplaySize(1));
+  }
+
+  @Test
+  public void sendParam() throws Exception {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+  }
+
+  private void sendParam(Connection con) throws Exception {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE VarbinaryCodec2");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO VarbinaryCodec2(t1) VALUES (?)")) {
+      prep.setBytes(1, null);
+      prep.execute();
+      prep.setBytes(1, "e🌟1".getBytes(StandardCharsets.UTF_8));
+      prep.execute();
+      prep.setNull(1, Types.BLOB);
+      prep.execute();
+
+      prep.setObject(1, "e🌟2".getBytes(StandardCharsets.UTF_8));
+      prep.execute();
+      prep.setObject(1, "e🌟3".getBytes(StandardCharsets.UTF_8), Types.VARBINARY);
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM VarbinaryCodec2");
+    assertTrue(rs.next());
+    assertNull(rs.getBytes(1));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟1".getBytes(StandardCharsets.UTF_8), rs.getBytes(1));
+
+    assertTrue(rs.next());
+    assertNull(rs.getBytes(1));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟2".getBytes(StandardCharsets.UTF_8), rs.getBytes(1));
+
+    assertTrue(rs.next());
+    assertArrayEquals("e🌟3".getBytes(StandardCharsets.UTF_8), rs.getBytes(1));
+    con.commit();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/VarcharCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/VarcharCodecTest.java
new file mode 100644
index 0000000..fc588b3
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/VarcharCodecTest.java
@@ -0,0 +1,1065 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.MariaDbClob;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class VarcharCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void after2() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS StringCodec");
+    stmt.execute("DROP TABLE IF EXISTS StringParamCodec");
+    stmt.execute("DROP TABLE IF EXISTS StringCodecWrong");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    after2();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute(
+        "CREATE TABLE StringCodec (t1 VARCHAR(255), t2 VARCHAR(30), t3 VARCHAR(20), t4 VARCHAR(20))"
+            + " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+    stmt.execute(
+        "INSERT INTO StringCodec VALUES ('0', '1', 'some🌟', null), "
+            + "('2011-01-01', '2010-12-31 23:59:59.152', '23:54:51.840010', null), "
+            + "('aaaa-bb-cc', '0000-00-00 00:00:00', '23:54:51.840010', null),"
+            + "('', '', '', null)");
+    stmt.execute(
+        "CREATE TABLE StringParamCodec(id int not null primary key auto_increment, t1 VARCHAR(20)) "
+            + "CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
+    stmt.execute(
+        "CREATE TABLE StringCodecWrong (t1 VARCHAR(20)) CHARACTER SET utf8mb4 COLLATE"
+            + " utf8mb4_unicode_ci");
+
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from StringCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from StringCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getObject(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getObject(2));
+    assertEquals("1", rs.getObject("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getObject(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, 0);
+    testObject(rs, String.class, "0");
+    testObject(rs, Byte.class, Byte.valueOf("0"));
+    testObject(rs, Long.class, 0L);
+    testObject(rs, Short.class, (short) 0);
+    testObject(rs, BigDecimal.class, BigDecimal.valueOf(0));
+    testObject(rs, BigInteger.class, BigInteger.valueOf(0));
+    testObject(rs, Double.class, (double) 0);
+    testObject(rs, Float.class, (float) 0);
+    testObject(rs, Byte.class, (byte) 0);
+    testArrObject(rs, new byte[] {(byte) '0'});
+    testObject(rs, Boolean.class, Boolean.FALSE);
+    testObject(rs, Clob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, NClob.class, new MariaDbClob("0".getBytes()));
+    testObject(rs, InputStream.class, new MariaDbClob("0".getBytes()).getBinaryStream());
+    testObject(rs, Reader.class, new StringReader("0"));
+    rs.next();
+    testObject(rs, LocalDate.class, LocalDate.parse("2011-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2011-01-01T00:00"));
+    testObject(rs, LocalTime.class, LocalTime.parse("23:54:51.840010"), 3);
+    Time t = Time.valueOf("23:54:51");
+    testObject(rs, Time.class, new Time(t.getTime() + 840), 3);
+    testObject(rs, Date.class, Date.valueOf("2011-01-01"));
+    Timestamp tt = Timestamp.valueOf("2010-12-31 23:59:59");
+    testObject(rs, Timestamp.class, new Timestamp(tt.getTime() + 152), 2);
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2011-01-01T00:00").atZone(ZoneId.systemDefault()));
+    testErrObject(rs, BigInteger.class);
+    testErrObject(rs, OffsetDateTime.class);
+    testErrObject(rs, OffsetTime.class);
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-12-31"), 2);
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getString(2));
+    assertEquals("1", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals("0", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1", rs.getNString(2));
+    assertEquals("1", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("some🌟", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertFalse(rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(2));
+    assertTrue(rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertTrue(rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertFalse(rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    assertEquals((byte) 0, rs.getByte(1));
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 1, rs.getByte(2));
+    assertEquals((byte) 1, rs.getByte("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getByte(3),
+        "value 'some\uD83C\uDF1F' (VARSTRING) cannot be decoded as Byte");
+    assertFalse(rs.wasNull());
+    assertEquals((byte) 0, rs.getByte(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    rs.next();
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getByte(1),
+        "value '' (VARSTRING) cannot be decoded as Byte");
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+    getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getShort(2));
+    assertEquals(1, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getShort(3), "value 'some🌟' cannot be decoded as Short");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(0, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1, rs.getInt(2));
+    assertEquals(1, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getInt(3), "value 'some🌟' cannot be decoded as Integer");
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(0L, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1L, rs.getLong(2));
+    assertEquals(1L, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getLong(3),
+        "value 'some\uD83C\uDF1F' cannot be decoded as Long");
+    assertFalse(rs.wasNull());
+    assertEquals(0L, rs.getLong(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(0F, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1F, rs.getFloat(2));
+    assertEquals(1F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getFloat(3), "value 'some🌟' cannot be decoded as Float");
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(0D, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1D, rs.getDouble(2));
+    assertEquals(1D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDouble(3),
+        "value 'some🌟' cannot be decoded as Double");
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(BigDecimal.ZERO, rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal(2));
+    assertEquals(BigDecimal.ONE, rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBigDecimal(3),
+        "value 'some🌟' cannot be decoded as BigDecimal");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(1),
+        "value '0' (VARSTRING) cannot be decoded as Date");
+    rs.next();
+    assertEquals("2011-01-01", rs.getDate(1).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate(2).toString());
+    assertFalse(rs.wasNull());
+    assertEquals("2010-12-31", rs.getDate("t2alias").toString());
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(3),
+        "value '23:54:51.840010' (VARSTRING) cannot be decoded as Date");
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getDate(1),
+        "value 'aaaa-bb-cc' (VARSTRING) cannot be decoded as Date");
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) throws SQLException {
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(1),
+        "VARSTRING value '2011-01-01' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getTime(2),
+        "VARSTRING value '2010-12-31 23:59:59.152' cannot be decoded as Time");
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime(3).getTime());
+    assertEquals(Time.valueOf("23:54:51").getTime() + 840, rs.getTime("t3alias").getTime());
+    Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+    assertEquals(86091840, rs.getTime(3, utc).getTime());
+    assertEquals(86091840, rs.getTime("t3alias", utc).getTime());
+
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getLocalTime() throws SQLException {
+    getLocalTime(get());
+  }
+
+  @Test
+  public void getLocalTimePrepare() throws SQLException {
+    getLocalTime(getPrepare(sharedConn));
+    getLocalTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalTime(ResultSet rs) throws SQLException {
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(1, LocalTime.class),
+        "value '2011-01-01' (VARSTRING) cannot be decoded as LocalTime");
+    assertFalse(rs.wasNull());
+
+    assertEquals(LocalTime.parse("23:59:59.152"), rs.getObject(2, LocalTime.class));
+    assertEquals(LocalTime.parse("23:54:51.840010"), rs.getObject(3, LocalTime.class));
+    assertEquals(LocalTime.parse("23:54:51.840010"), rs.getObject("t3alias", LocalTime.class));
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(get());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPrepare(sharedConn));
+    getDuration(getPrepare(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(1, Duration.class),
+        "VARSTRING value '0' cannot be decoded as Time");
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(1, Duration.class),
+        "VARSTRING value '2011-01-01' cannot be decoded as Time");
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(2, Duration.class),
+        "VARSTRING value '2010-12-31 23:59:59.152' cannot be decoded as Time");
+    assertEquals(Duration.parse("PT23H54M51.84001S"), rs.getObject(3, Duration.class));
+    assertEquals(Duration.parse("PT23H54M51.84001S"), rs.getObject("t3alias", Duration.class));
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    rs.next();
+
+    assertEquals(Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2011-01-01 00:00:00").getTime() + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152, rs.getTimestamp(2).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime() + 152,
+        rs.getTimestamp("t2alias").getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-12-31 23:59:59").getTime()
+            + 152
+            + TimeZone.getDefault().getDSTSavings(),
+        rs.getTimestamp("t2alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getLocalDateTime() throws SQLException {
+    getLocalDateTime(get());
+  }
+
+  @Test
+  public void getLocalDateTimePrepare() throws SQLException {
+    getLocalDateTime(getPrepare(sharedConn));
+    getLocalDateTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDateTime(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(1, LocalDateTime.class),
+        "value '0' (VARSTRING) cannot be decoded as LocalDateTime");
+    rs.next();
+    assertEquals(LocalDateTime.parse("2011-01-01T00:00:00"), rs.getObject(1, LocalDateTime.class));
+    assertFalse(rs.wasNull());
+    assertEquals(
+        LocalDateTime.parse("2010-12-31T23:59:59.152"), rs.getObject(2, LocalDateTime.class));
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(1, LocalDateTime.class),
+        "value 'aaaa-bb-cc' (VARSTRING) cannot be decoded as LocalDateTime");
+    assertNull(rs.getObject(2, LocalDateTime.class));
+  }
+
+  @Test
+  public void getLocalDate() throws SQLException {
+    getLocalDate(get());
+  }
+
+  @Test
+  public void getLocalDatePrepare() throws SQLException {
+    getLocalDate(getPrepare(sharedConn));
+    getLocalDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDate(ResultSet rs) throws SQLException {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(1, LocalDate.class),
+        "value '0' (VARSTRING) cannot be decoded as Date");
+    rs.next();
+    assertEquals(LocalDate.parse("2011-01-01"), rs.getObject(1, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDate.parse("2010-12-31"), rs.getObject(2, LocalDate.class));
+    rs.next();
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getObject(1, LocalDate.class),
+        "value 'aaaa-bb-cc' (VARSTRING) cannot be decoded as Date");
+    assertNull(rs.getObject(2, LocalDate.class));
+  }
+
+  @Test
+  public void getAsciiStream() throws Exception {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws Exception {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getAsciiStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getAsciiStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getAsciiStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getAsciiStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getUnicodeStream() throws Exception {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws Exception {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getUnicodeStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getUnicodeStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)),
+        rs.getUnicodeStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getUnicodeStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBinaryStream() throws Exception {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws Exception {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) throws Exception {
+    assertStreamEquals(new ByteArrayInputStream("0".getBytes()), rs.getBinaryStream(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream(2));
+    assertStreamEquals(new ByteArrayInputStream("1".getBytes()), rs.getBinaryStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(
+        new ByteArrayInputStream("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getBinaryStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBinaryStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) throws SQLException {
+    assertArrayEquals("0".getBytes(), rs.getBytes(1));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("1".getBytes(), rs.getBytes(2));
+    assertArrayEquals("1".getBytes(), rs.getBytes("t2alias"));
+    assertFalse(rs.wasNull());
+    assertArrayEquals("some🌟".getBytes(StandardCharsets.UTF_8), rs.getBytes(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBytes(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getCharacterStream() throws Exception {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws Exception {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNCharacterStream() throws Exception {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws Exception {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) throws Exception {
+    assertReaderEquals(new StringReader("0"), rs.getNCharacterStream(1));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream(2));
+    assertReaderEquals(new StringReader("1"), rs.getNCharacterStream("t2alias"));
+    assertFalse(rs.wasNull());
+    assertReaderEquals(new StringReader("some🌟"), rs.getNCharacterStream(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNCharacterStream(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getBlob() throws Exception {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws Exception {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getBlob(1),
+        "Data type VARSTRING (not binary) cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getClob() throws Exception {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws Exception {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getNClob() throws Exception {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws Exception {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) throws Exception {
+    assertStreamEquals(new MariaDbClob("0".getBytes()), rs.getNClob(1));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob(2));
+    assertStreamEquals(new MariaDbClob("1".getBytes()), rs.getNClob("t2alias"));
+    assertFalse(rs.wasNull());
+    assertStreamEquals(new MariaDbClob("some🌟".getBytes(StandardCharsets.UTF_8)), rs.getNClob(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNClob(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("VARCHAR", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.lang.String", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.VARCHAR, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    if (!isXpand()) {
+      assertEquals(255, meta.getPrecision(1));
+      assertEquals(255, meta.getColumnDisplaySize(1));
+    }
+
+    try (ResultSet rs2 = sharedConn.getMetaData().getColumns(database, null, "StringCodec", "t1")) {
+      rs2.next();
+      assertEquals(String.class, rs2.getObject("TYPE_NAME").getClass());
+    }
+  }
+
+  @Test
+  public void sendParam() throws SQLException {
+    sendParam(sharedConn);
+    sendParam(sharedConnBinary);
+    try (Connection con = createCon()) {
+      java.sql.Statement stmt = con.createStatement();
+      stmt.execute("SET sql_mode = concat(@@sql_mode,',NO_BACKSLASH_ESCAPES')");
+      sendParam(con);
+    }
+  }
+
+  private void sendParam(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("TRUNCATE TABLE StringParamCodec");
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    try (PreparedStatement prep =
+        con.prepareStatement("INSERT INTO StringParamCodec(t1) VALUES (?)")) {
+      prep.setString(1, "e'\\n🌟'\\'1Ã");
+      prep.execute();
+      prep.setString(1, null);
+      prep.execute();
+      prep.setObject(1, "e🌟2");
+      prep.execute();
+      prep.setObject(1, null);
+      prep.execute();
+      prep.setObject(1, "e🌟3", Types.VARCHAR);
+      prep.execute();
+      prep.setObject(1, null, Types.VARCHAR);
+      prep.execute();
+      prep.setAsciiStream(1, new ByteArrayInputStream("e🌟3654".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setAsciiStream(
+          1, new ByteArrayInputStream("e🌟3654".getBytes(StandardCharsets.UTF_8)), 7);
+      prep.execute();
+      prep.setAsciiStream(
+          1, new ByteArrayInputStream("e🌟4654".getBytes(StandardCharsets.UTF_8)), 7L);
+      prep.execute();
+      prep.setAsciiStream(1, new ByteArrayInputStream("e🌟3654".getBytes(StandardCharsets.UTF_8)));
+      prep.execute();
+      prep.setAsciiStream(
+          1, new ByteArrayInputStream("e🌟3654".getBytes(StandardCharsets.UTF_8)), 7);
+      prep.execute();
+      prep.setAsciiStream(
+          1, new ByteArrayInputStream("e🌟4654".getBytes(StandardCharsets.UTF_8)), 7L);
+      prep.execute();
+      prep.setNString(1, "e🌟13");
+      prep.execute();
+      prep.setNString(1, "e🌟12");
+      prep.execute();
+    }
+
+    ResultSet rs =
+        con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
+            .executeQuery("SELECT * FROM StringParamCodec");
+    assertTrue(rs.next());
+    assertEquals("e'\\n🌟'\\'1Ã", rs.getString(2));
+    rs.updateString("t1", "f🌟12");
+    rs.updateRow();
+    assertEquals("f🌟12", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertNull(rs.getURL(2));
+    rs.updateString(2, "f🌟125");
+    rs.updateRow();
+    assertEquals("f🌟125", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟2", rs.getString(2));
+    rs.updateString(2, null);
+    rs.updateRow();
+    assertNull(rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    rs.updateObject(2, "f🌟125", JDBCType.VARCHAR, 5);
+    rs.updateRow();
+    assertEquals("f🌟12", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟3", rs.getString(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟3654", rs.getString(2));
+    rs.updateAsciiStream(
+        "t1", new ByteArrayInputStream("f🌟3654".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("f🌟3654", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟36", rs.getString(2));
+    rs.updateAsciiStream(
+        "t1", new ByteArrayInputStream("f🌟3654".getBytes(StandardCharsets.UTF_8)), 7);
+    rs.updateRow();
+    assertEquals("f🌟36", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟46", rs.getString(2));
+    rs.updateAsciiStream(
+        "t1", new ByteArrayInputStream("f🌟4654".getBytes(StandardCharsets.UTF_8)), 7L);
+    rs.updateRow();
+    assertEquals("f🌟46", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟3654", rs.getString(2));
+    rs.updateAsciiStream(2, new ByteArrayInputStream("f🌟3654".getBytes(StandardCharsets.UTF_8)));
+    rs.updateRow();
+    assertEquals("f🌟3654", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟36", rs.getString(2));
+    rs.updateAsciiStream(
+        2, new ByteArrayInputStream("f🌟3654".getBytes(StandardCharsets.UTF_8)), 7);
+    rs.updateRow();
+    assertEquals("f🌟36", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟46", rs.getString(2));
+    rs.updateAsciiStream(
+        2, new ByteArrayInputStream("f🌟4654".getBytes(StandardCharsets.UTF_8)), 7L);
+    rs.updateRow();
+    assertEquals("f🌟46", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟13", rs.getString(2));
+    rs.updateNString(2, "f🌟14");
+    rs.updateRow();
+    assertEquals("f🌟14", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟12", rs.getString(2));
+    rs.updateNString("t1", "http://f🌟15");
+    rs.updateRow();
+    assertEquals("http://f🌟15", rs.getString(2));
+
+    rs = stmt.executeQuery("SELECT * FROM StringParamCodec");
+    assertTrue(rs.next());
+    assertEquals("f🌟12", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟125", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟12", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("e🌟3", rs.getString(2));
+    assertTrue(rs.next());
+    assertNull(rs.getString(2));
+    assertTrue(rs.next());
+    assertEquals("f🌟3654", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟36", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟46", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟3654", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟36", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟46", rs.getString(2));
+
+    assertTrue(rs.next());
+    assertEquals("f🌟14", rs.getString(2));
+    assertEquals("f🌟14", rs.getObject(2, (Class<String>) null));
+
+    assertTrue(rs.next());
+    assertEquals("http://f🌟15", rs.getObject(2, (Map<String, Class<?>>) null));
+    assertEquals("http://f🌟15", rs.getObject("t1", (Map<String, Class<?>>) null));
+    Map<String, Class<?>> empty = new HashMap<>();
+    assertEquals("http://f🌟15", rs.getObject("t1", empty));
+    assertEquals("http://f🌟15", rs.getURL(2).toString());
+    assertEquals("http://f🌟15", rs.getURL("t1").toString());
+    con.commit();
+  }
+
+  @Test
+  public void wrongUtf8String() throws SQLException {
+    final byte[] utf8WrongBytes =
+        new byte[] {(byte) 0xc2, (byte) 0f, (byte) 0xDB, (byte) 0, (byte) 0xE1, (byte) 0};
+    String st = new String(utf8WrongBytes);
+
+    wrongUtf8(sharedConn, st);
+    wrongUtf8(sharedConnBinary, st);
+  }
+
+  private void wrongUtf8(Connection con, String wrong) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("INSERT INTO StringCodecWrong VALUES ('" + wrong + "')");
+    ResultSet rs = stmt.executeQuery("SELECT * FROM StringCodecWrong");
+    rs.next();
+    assertEquals(wrong, rs.getString(1));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/codec/YearCodecTest.java b/src/test/java/org/mariadb/jdbc/integration/codec/YearCodecTest.java
new file mode 100644
index 0000000..c303f38
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/codec/YearCodecTest.java
@@ -0,0 +1,770 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.codec;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.*;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class YearCodecTest extends CommonCodecTest {
+  @AfterAll
+  public static void drop() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS YearCodec");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    drop();
+    Statement stmt = sharedConn.createStatement();
+    if (isMariaDBServer() && !isXpand()) {
+      stmt.execute("CREATE TABLE YearCodec (t1 YEAR(2), t2 YEAR(4), t3 YEAR(4), t4 YEAR(4))");
+      stmt.execute(
+          "INSERT INTO YearCodec VALUES ('2010', '1901', '2155', null), (80, '1901', '2155',"
+              + " null)");
+    } else {
+      stmt.execute("CREATE TABLE YearCodec (t1 YEAR(4), t2 YEAR(4), t3 YEAR(4), t4 YEAR(4))");
+      stmt.execute(
+          "INSERT INTO YearCodec VALUES ('2010', '1901', '2155', null), (1980, '1901', '2155',"
+              + " null)");
+    }
+    stmt.execute("FLUSH TABLES");
+  }
+
+  private ResultSet get() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    ResultSet rs =
+        stmt.executeQuery(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from YearCodec");
+    assertTrue(rs.next());
+    sharedConn.commit();
+    return rs;
+  }
+
+  private ResultSet getPrepare(Connection con) throws SQLException {
+    java.sql.Statement stmt = con.createStatement();
+    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
+    PreparedStatement preparedStatement =
+        con.prepareStatement(
+            "select t1 as t1alias, t2 as t2alias, t3 as t3alias, t4 as t4alias from YearCodec"
+                + " WHERE 1 > ?");
+    preparedStatement.closeOnCompletion();
+    preparedStatement.setInt(1, 0);
+    ResultSet rs = preparedStatement.executeQuery();
+    assertTrue(rs.next());
+    con.commit();
+    return rs;
+  }
+
+  @Test
+  public void getObject() throws SQLException {
+    getObject(get());
+  }
+
+  @Test
+  public void getObjectPrepare() throws SQLException {
+    getObject(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getObject(getPrepare(sharedConnBinary));
+  }
+
+  public void getObject(ResultSet rs) throws SQLException {
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("2010-01-01").getTime(), ((Date) rs.getObject(1)).getTime());
+    assertFalse(rs.wasNull());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("1901-01-01").getTime(), ((Date) rs.getObject(2)).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("2155-01-01").getTime(), ((Date) rs.getObject(3)).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(Date.valueOf("1980-01-01").getTime(), ((Date) rs.getObject(1)).getTime());
+  }
+
+  @Test
+  public void getObjectType() throws Exception {
+    getObjectType(get());
+  }
+
+  @Test
+  public void getObjectTypePrepare() throws Exception {
+    getObjectType(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getObjectType(getPrepare(sharedConnBinary));
+  }
+
+  public void getObjectType(ResultSet rs) throws Exception {
+    testObject(rs, Integer.class, isMariaDBServer() && !isXpand() ? 10 : 2010);
+    testObject(rs, String.class, isMariaDBServer() && !isXpand() ? "10" : "2010");
+    testObject(rs, Long.class, isMariaDBServer() && !isXpand() ? 10L : 2010L);
+    testObject(rs, Short.class, (short) (isMariaDBServer() && !isXpand() ? 10 : 2010));
+    testObject(
+        rs,
+        BigDecimal.class,
+        isMariaDBServer() && !isXpand() ? BigDecimal.TEN : BigDecimal.valueOf(2010));
+    testObject(
+        rs,
+        BigInteger.class,
+        isMariaDBServer() && !isXpand() ? BigInteger.TEN : BigInteger.valueOf(2010));
+    testObject(rs, Double.class, isMariaDBServer() && !isXpand() ? 10d : 2010d);
+    testObject(rs, Float.class, isMariaDBServer() && !isXpand() ? 10f : 2010f);
+    if (isMariaDBServer() && !isXpand()) {
+      testObject(rs, Byte.class, (byte) 0x0a);
+    } else {
+      testErrObject(rs, Byte.class);
+    }
+    testErrObject(rs, byte[].class);
+    testObject(rs, Boolean.class, true);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testObject(rs, LocalDate.class, LocalDate.parse("2010-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("2010-01-01T00:00:00"));
+    testErrObject(rs, LocalTime.class);
+    testErrObject(rs, Time.class);
+    testObject(
+        rs,
+        BigInteger.class,
+        isMariaDBServer() && !isXpand() ? BigInteger.TEN : BigInteger.valueOf(2010));
+    testObject(rs, Timestamp.class, Timestamp.valueOf("2010-01-01 00:00:00"));
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("2010-01-01T00:00:00").atZone(ZoneId.systemDefault()));
+    testObject(rs, java.util.Date.class, Date.valueOf("2010-01-01"));
+    rs.next();
+
+    testObject(rs, Integer.class, isMariaDBServer() && !isXpand() ? 80 : 1980);
+    testObject(rs, String.class, isMariaDBServer() && !isXpand() ? "80" : "1980");
+    testObject(rs, Long.class, isMariaDBServer() && !isXpand() ? 80L : 1980L);
+    testObject(rs, Short.class, (short) (isMariaDBServer() && !isXpand() ? 80 : 1980));
+    testObject(
+        rs, BigDecimal.class, BigDecimal.valueOf(isMariaDBServer() && !isXpand() ? 80 : 1980));
+    testObject(
+        rs, BigInteger.class, BigInteger.valueOf(isMariaDBServer() && !isXpand() ? 80 : 1980));
+    testObject(rs, Double.class, isMariaDBServer() && !isXpand() ? 80d : 1980d);
+    testObject(rs, Float.class, isMariaDBServer() && !isXpand() ? 80f : 1980f);
+
+    if (isMariaDBServer() && !isXpand()) {
+      testObject(rs, Byte.class, (byte) 80);
+    } else {
+      testErrObject(rs, Byte.class);
+    }
+    testErrObject(rs, byte[].class);
+    testObject(rs, Boolean.class, true);
+    testErrObject(rs, Clob.class);
+    testErrObject(rs, NClob.class);
+    testErrObject(rs, InputStream.class);
+    testErrObject(rs, Reader.class);
+    testObject(rs, LocalDate.class, LocalDate.parse("1980-01-01"));
+    testObject(rs, LocalDateTime.class, LocalDateTime.parse("1980-01-01T00:00:00"));
+    testErrObject(rs, LocalTime.class);
+    testErrObject(rs, Time.class);
+    testObject(
+        rs,
+        BigInteger.class,
+        isMariaDBServer() && !isXpand() ? BigInteger.valueOf(80) : BigInteger.valueOf(1980));
+    testObject(rs, Timestamp.class, Timestamp.valueOf("1980-01-01 00:00:00"));
+    testObject(
+        rs,
+        ZonedDateTime.class,
+        LocalDateTime.parse("1980-01-01T00:00:00").atZone(ZoneId.systemDefault()));
+    testObject(rs, java.util.Date.class, Date.valueOf("1980-01-01"));
+  }
+
+  @Test
+  public void getString() throws SQLException {
+    getString(get());
+  }
+
+  @Test
+  public void getStringPrepare() throws SQLException {
+    getString(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getString(getPrepare(sharedConnBinary));
+  }
+
+  public void getString(ResultSet rs) throws SQLException {
+    assertEquals(isMariaDBServer() && !isXpand() ? "10" : "2010", rs.getString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1901", rs.getString(2));
+    assertEquals("1901", rs.getString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("2155", rs.getString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getString(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(isMariaDBServer() && !isXpand() ? "80" : "1980", rs.getString(1));
+  }
+
+  @Test
+  public void getNString() throws SQLException {
+    getNString(get());
+  }
+
+  @Test
+  public void getNStringPrepare() throws SQLException {
+    getNString(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getNString(getPrepare(sharedConnBinary));
+  }
+
+  public void getNString(ResultSet rs) throws SQLException {
+    assertEquals(isMariaDBServer() && !isXpand() ? "10" : "2010", rs.getNString(1));
+    assertFalse(rs.wasNull());
+    assertEquals("1901", rs.getNString(2));
+    assertEquals("1901", rs.getNString("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals("2155", rs.getNString(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getNString(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(isMariaDBServer() && !isXpand() ? "80" : "1980", rs.getString(1));
+  }
+
+  @Test
+  public void getBoolean() throws SQLException {
+    getBoolean(get());
+  }
+
+  @Test
+  public void getBooleanPrepare() throws SQLException {
+    getBoolean(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getBoolean(getPrepare(sharedConnBinary));
+  }
+
+  public void getBoolean(ResultSet rs) throws SQLException {
+    assertEquals(true, rs.getBoolean(1));
+    assertFalse(rs.wasNull());
+    assertEquals(true, rs.getBoolean(2));
+    assertEquals(true, rs.getBoolean("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(true, rs.getBoolean(3));
+    assertFalse(rs.wasNull());
+    assertEquals(false, rs.getBoolean(4));
+    assertTrue(rs.wasNull());
+  }
+
+  @Test
+  public void getByte() throws SQLException {
+    getByte(get());
+  }
+
+  @Test
+  public void getBytePrepare() throws SQLException {
+    getByte(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getByte(getPrepare(sharedConnBinary));
+  }
+
+  public void getByte(ResultSet rs) throws SQLException {
+    if (isMariaDBServer() && !isXpand()) {
+      assertEquals(Byte.valueOf("10"), rs.getByte(1));
+    } else {
+      Common.assertThrowsContains(SQLDataException.class, () -> rs.getByte(1), "byte overflow");
+    }
+    assertFalse(rs.wasNull());
+    Common.assertThrowsContains(SQLDataException.class, () -> rs.getByte(2), "byte overflow");
+    Common.assertThrowsContains(
+        SQLDataException.class, () -> rs.getByte("t2alias"), "byte overflow");
+    assertFalse(rs.wasNull());
+  }
+
+  @Test
+  public void getShort() throws SQLException {
+    getShort(get());
+  }
+
+  @Test
+  public void getShortPrepare() throws SQLException {
+    getShort(getPrepare(sharedConn));
+
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getShort(getPrepare(sharedConnBinary));
+  }
+
+  public void getShort(ResultSet rs) throws SQLException {
+    assertEquals(isMariaDBServer() && !isXpand() ? 10 : 2010, rs.getShort(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1901, rs.getShort(2));
+    assertEquals(1901, rs.getShort("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(2155, rs.getShort(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getShort(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(isMariaDBServer() && !isXpand() ? 80 : 1980, rs.getShort(1));
+  }
+
+  @Test
+  public void getInt() throws SQLException {
+    getInt(get());
+  }
+
+  @Test
+  public void getIntPrepare() throws SQLException {
+    getInt(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getInt(getPrepare(sharedConnBinary));
+  }
+
+  public void getInt(ResultSet rs) throws SQLException {
+    assertEquals(isMariaDBServer() && !isXpand() ? 10 : 2010, rs.getInt(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1901, rs.getInt(2));
+    assertEquals(1901, rs.getInt("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(2155, rs.getInt(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getInt(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(isMariaDBServer() && !isXpand() ? 80 : 1980, rs.getInt(1));
+  }
+
+  @Test
+  public void getLong() throws SQLException {
+    getLong(get());
+  }
+
+  @Test
+  public void getLongPrepare() throws SQLException {
+    getLong(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getLong(getPrepare(sharedConnBinary));
+  }
+
+  public void getLong(ResultSet rs) throws SQLException {
+    assertEquals(isMariaDBServer() && !isXpand() ? 10 : 2010, rs.getLong(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1901, rs.getLong(2));
+    assertEquals(1901, rs.getLong("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(2155, rs.getLong(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0, rs.getLong(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(isMariaDBServer() && !isXpand() ? 80 : 1980, rs.getLong(1));
+  }
+
+  @Test
+  public void getFloat() throws SQLException {
+    getFloat(get());
+  }
+
+  @Test
+  public void getFloatPrepare() throws SQLException {
+    getFloat(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getFloat(getPrepare(sharedConnBinary));
+  }
+
+  public void getFloat(ResultSet rs) throws SQLException {
+    assertEquals(isMariaDBServer() && !isXpand() ? 10F : 2010f, rs.getFloat(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1901F, rs.getFloat(2));
+    assertEquals(1901F, rs.getFloat("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(2155F, rs.getFloat(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0F, rs.getFloat(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(isMariaDBServer() && !isXpand() ? 80f : 1980f, rs.getFloat(1));
+  }
+
+  @Test
+  public void getDouble() throws SQLException {
+    getDouble(get());
+  }
+
+  @Test
+  public void getDoublePrepare() throws SQLException {
+    getDouble(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getDouble(getPrepare(sharedConnBinary));
+  }
+
+  public void getDouble(ResultSet rs) throws SQLException {
+    assertEquals(isMariaDBServer() && !isXpand() ? 10d : 2010d, rs.getDouble(1));
+    assertFalse(rs.wasNull());
+    assertEquals(1901D, rs.getDouble(2));
+    assertEquals(1901D, rs.getDouble("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(2155D, rs.getDouble(3));
+    assertFalse(rs.wasNull());
+    assertEquals(0D, rs.getDouble(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(isMariaDBServer() && !isXpand() ? 80d : 1980d, rs.getDouble(1));
+  }
+
+  @Test
+  public void getBigDecimal() throws SQLException {
+    getBigDecimal(get());
+  }
+
+  @Test
+  public void getBigDecimalPrepare() throws SQLException {
+    getBigDecimal(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getBigDecimal(getPrepare(sharedConnBinary));
+  }
+
+  public void getBigDecimal(ResultSet rs) throws SQLException {
+    assertEquals(
+        isMariaDBServer() && !isXpand() ? BigDecimal.TEN : BigDecimal.valueOf(2010),
+        rs.getBigDecimal(1));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(1901), rs.getBigDecimal(2));
+    assertEquals(BigDecimal.valueOf(1901), rs.getBigDecimal("t2alias"));
+    assertFalse(rs.wasNull());
+    assertEquals(BigDecimal.valueOf(2155), rs.getBigDecimal(3));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getBigDecimal(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(
+        isMariaDBServer() && !isXpand() ? BigDecimal.valueOf(80) : BigDecimal.valueOf(1980),
+        rs.getBigDecimal(1));
+  }
+
+  @Test
+  public void getDate() throws SQLException {
+    getDate(get());
+  }
+
+  @Test
+  public void getDatePrepare() throws SQLException {
+    getDate(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getDate(ResultSet rs) throws SQLException {
+    assertEquals(Date.valueOf("2010-01-01").getTime(), rs.getDate(1).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("1901-01-01").getTime(), rs.getDate(2).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Date.valueOf("2155-01-01").getTime(), rs.getDate(3).getTime());
+    assertFalse(rs.wasNull());
+    assertNull(rs.getDate(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(Date.valueOf("1980-01-01").getTime(), rs.getDate(1).getTime());
+  }
+
+  @Test
+  public void getTime() throws SQLException {
+    getTime(get());
+  }
+
+  @Test
+  public void getTimePrepare() throws SQLException {
+    getTime(getPrepare(sharedConn));
+    getTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getTime(1), "Data type YEAR cannot be decoded as Time");
+  }
+
+  @Test
+  public void getDuration() throws SQLException {
+    getDuration(get());
+  }
+
+  @Test
+  public void getDurationPrepare() throws SQLException {
+    getDuration(getPrepare(sharedConn));
+    getDuration(getPrepare(sharedConnBinary));
+  }
+
+  public void getDuration(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, Duration.class),
+        "Type class java.time.Duration not supported type for YEAR type");
+  }
+
+  @Test
+  public void getLocalTime() throws SQLException {
+    getLocalTime(get());
+  }
+
+  @Test
+  public void getLocalTimePrepare() throws SQLException {
+    getLocalTime(getPrepare(sharedConn));
+    getLocalTime(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalTime(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(1, LocalTime.class),
+        "Type class java.time.LocalTime not supported type for YEAR type");
+  }
+
+  @Test
+  public void getLocalDate() throws SQLException {
+    getLocalDate(get());
+  }
+
+  @Test
+  public void getLocalDatePrepare() throws SQLException {
+    getLocalDate(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getLocalDate(getPrepare(sharedConnBinary));
+  }
+
+  public void getLocalDate(ResultSet rs) throws SQLException {
+    assertEquals(LocalDate.parse("2010-01-01"), rs.getObject(1, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDate.parse("1901-01-01"), rs.getObject(2, LocalDate.class));
+    assertEquals(LocalDate.parse("1901-01-01"), rs.getObject("t2alias", LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertEquals(LocalDate.parse("2155-01-01"), rs.getObject(3, LocalDate.class));
+    assertFalse(rs.wasNull());
+    assertNull(rs.getObject(4, LocalDate.class));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(LocalDate.parse("1980-01-01"), rs.getObject(1, LocalDate.class));
+  }
+
+  @Test
+  public void getTimestamp() throws SQLException {
+    getTimestamp(get());
+  }
+
+  @Test
+  public void getTimestampPrepare() throws SQLException {
+    getTimestamp(getPrepare(sharedConn));
+    // https://jira.mariadb.org/browse/XPT-269
+    if (!isXpand()) getTimestamp(getPrepare(sharedConnBinary));
+  }
+
+  public void getTimestamp(ResultSet rs) throws SQLException {
+    assertEquals(Timestamp.valueOf("2010-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+    assertEquals(
+        1262304000000L,
+        rs.getTimestamp(1, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertEquals(
+        Timestamp.valueOf("2010-01-01 00:00:00").getTime(), rs.getTimestamp("t1alias").getTime());
+    assertEquals(
+        1262304000000L,
+        rs.getTimestamp("t1alias", Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Timestamp.valueOf("1901-01-01 00:00:00").getTime(), rs.getTimestamp(2).getTime());
+    assertEquals(
+        -2177452800000L,
+        rs.getTimestamp(2, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+
+    assertEquals(Timestamp.valueOf("2155-01-01 00:00:00").getTime(), rs.getTimestamp(3).getTime());
+    assertEquals(
+        5838048000000L,
+        rs.getTimestamp(3, Calendar.getInstance(TimeZone.getTimeZone("UTC"))).getTime());
+    assertFalse(rs.wasNull());
+    assertEquals(Timestamp.valueOf("2155-01-01 00:00:00"), rs.getTimestamp(3));
+    assertNull(rs.getTimestamp(4));
+    assertTrue(rs.wasNull());
+    rs.next();
+    assertEquals(Timestamp.valueOf("1980-01-01 00:00:00").getTime(), rs.getTimestamp(1).getTime());
+  }
+
+  @Test
+  public void getAsciiStream() throws SQLException {
+    getAsciiStream(get());
+  }
+
+  @Test
+  public void getAsciiStreamPrepare() throws SQLException {
+    getAsciiStream(getPrepare(sharedConn));
+    getAsciiStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getAsciiStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getAsciiStream(1),
+        "Data type YEAR cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getUnicodeStream() throws SQLException {
+    getUnicodeStream(get());
+  }
+
+  @Test
+  public void getUnicodeStreamPrepare() throws SQLException {
+    getUnicodeStream(getPrepare(sharedConn));
+    getUnicodeStream(getPrepare(sharedConnBinary));
+  }
+
+  @SuppressWarnings("deprecation")
+  public void getUnicodeStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getUnicodeStream(1),
+        "Data type YEAR cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBinaryStream() throws SQLException {
+    getBinaryStream(get());
+  }
+
+  @Test
+  public void getBinaryStreamPrepare() throws SQLException {
+    getBinaryStream(getPrepare(sharedConn));
+    getBinaryStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getBinaryStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getBinaryStream(1),
+        "Data type YEAR cannot be decoded as Stream");
+  }
+
+  @Test
+  public void getBytes() throws SQLException {
+    getBytes(get());
+  }
+
+  @Test
+  public void getBytesPrepare() throws SQLException {
+    getBytes(getPrepare(sharedConn));
+    getBytes(getPrepare(sharedConnBinary));
+  }
+
+  public void getBytes(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBytes(1), "Data type YEAR cannot be decoded as byte[]");
+  }
+
+  @Test
+  public void getCharacterStream() throws SQLException {
+    getCharacterStream(get());
+  }
+
+  @Test
+  public void getCharacterStreamPrepare() throws SQLException {
+    getCharacterStream(getPrepare(sharedConn));
+    getCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getCharacterStream(1),
+        "Data type YEAR cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getNCharacterStream() throws SQLException {
+    getNCharacterStream(get());
+  }
+
+  @Test
+  public void getNCharacterStreamPrepare() throws SQLException {
+    getNCharacterStream(getPrepare(sharedConn));
+    getNCharacterStream(getPrepare(sharedConnBinary));
+  }
+
+  public void getNCharacterStream(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLDataException.class,
+        () -> rs.getNCharacterStream(1),
+        "Data type YEAR cannot be decoded as Reader");
+  }
+
+  @Test
+  public void getBlob() throws SQLException {
+    getBlob(get());
+  }
+
+  @Test
+  public void getBlobPrepare() throws SQLException {
+    getBlob(getPrepare(sharedConn));
+    getBlob(getPrepare(sharedConnBinary));
+  }
+
+  public void getBlob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getBlob(1), "Data type YEAR cannot be decoded as Blob");
+  }
+
+  @Test
+  public void getClob() throws SQLException {
+    getClob(get());
+  }
+
+  @Test
+  public void getClobPrepare() throws SQLException {
+    getClob(getPrepare(sharedConn));
+    getClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getClob(1), "Data type YEAR cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getNClob() throws SQLException {
+    getNClob(get());
+  }
+
+  @Test
+  public void getNClobPrepare() throws SQLException {
+    getNClob(getPrepare(sharedConn));
+    getNClob(getPrepare(sharedConnBinary));
+  }
+
+  public void getNClob(ResultSet rs) {
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.getNClob(1), "Data type YEAR cannot be decoded as Clob");
+  }
+
+  @Test
+  public void getMetaData() throws SQLException {
+    ResultSet rs = get();
+    ResultSetMetaData meta = rs.getMetaData();
+    assertEquals("YEAR", meta.getColumnTypeName(1));
+    assertEquals(sharedConn.getCatalog(), meta.getCatalogName(1));
+    assertEquals("java.sql.Date", meta.getColumnClassName(1));
+    assertEquals("t1alias", meta.getColumnLabel(1));
+    assertEquals("t1", meta.getColumnName(1));
+    assertEquals(Types.DATE, meta.getColumnType(1));
+    assertEquals(4, meta.getColumnCount());
+    assertEquals(isMariaDBServer() && !isXpand() ? 2 : 4, meta.getPrecision(1));
+    assertEquals(0, meta.getScale(1));
+    assertEquals("", meta.getSchemaName(1));
+    assertEquals(isMariaDBServer() && !isXpand() ? 2 : 4, meta.getColumnDisplaySize(1));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/resultset/ReadResultSetTest.java b/src/test/java/org/mariadb/jdbc/integration/resultset/ReadResultSetTest.java
new file mode 100644
index 0000000..511b65b
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/resultset/ReadResultSetTest.java
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.resultset;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.*;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class ReadResultSetTest extends Common {
+
+  private final String NOT_SUPPORTED = "Not supported when using CONCUR_READ_ONLY concurrency";
+  private final Class<? extends java.lang.Exception> ns = SQLFeatureNotSupportedException.class;
+
+  @AfterAll
+  public static void after2() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE ResultSetTest");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS ResultSetTest");
+    stmt.execute("CREATE TABLE ResultSetTest (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("INSERT INTO ResultSetTest(t2) values (1),(2),(3),(4),(5),(6),(7),(8)");
+  }
+
+  @Test
+  public void nonUpdatableFields() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Assertions.assertNull(rs.getWarnings());
+    rs.next();
+    Common.assertThrowsContains(ns, () -> rs.updateArray(1, null), "Array are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateNull(1), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBoolean(1, true), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateByte(1, (byte) 0x00), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateShort(1, (short) 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateInt(1, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateLong(1, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateFloat(1, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDouble(1, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBigDecimal(1, BigDecimal.ZERO), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateString(1, ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNString(1, ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBytes(1, new byte[0]), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDate(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTime(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTimestamp(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream(1, null, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream(1, null, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream(1, null, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob(1, (Blob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob(1, (Clob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob(1, (InputStream) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob(1, (Reader) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob(1, (NClob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob(1, (Reader) null), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, () -> rs.updateArray("t1", null), "Array are not supported");
+
+    Common.assertThrowsContains(ns, () -> rs.updateNull("t1"), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBoolean("t1", true), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateByte("t1", (byte) 0x00), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateShort("t1", (short) 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateInt("t1", 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateLong("t1", 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateFloat("t1", 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDouble("t1", 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(
+        ns, () -> rs.updateBigDecimal("t1", BigDecimal.ZERO), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateString("t1", ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNString("t1", ""), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBytes("t1", new byte[0]), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateDate("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTime("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateTimestamp("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream("t1", null, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream("t1", null, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream("t1", null, 0L), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, () -> rs.updateBlob("t1", (Blob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob("t1", (InputStream) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob("t1", (Clob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob("t1", (Reader) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob("t1", (NClob) null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob("t1", (Reader) null), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, rs::insertRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::updateRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::deleteRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::refreshRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::cancelRowUpdates, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::moveToInsertRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::moveToCurrentRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::rowUpdated, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::rowInserted, NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, rs::rowDeleted, NOT_SUPPORTED);
+
+    Common.assertThrowsContains(
+        ns, () -> rs.updateRef(1, null), "Method ResultSet.updateRef not supported");
+    Common.assertThrowsContains(
+        ns, () -> rs.updateRef("t1", null), "Method ResultSet.updateRef not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateArray(1, null), "Array are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateArray("t1", null), "Array are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateRowId(1, null), "RowId are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateRowId("t1", null), "RowId are not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateSQLXML(1, null), "SQLXML not supported");
+    Common.assertThrowsContains(ns, () -> rs.updateSQLXML("t1", null), "SQLXML not supported");
+
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream("t1", null, 0), NOT_SUPPORTED);
+
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBlob("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateClob("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob(1, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNClob("t1", null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateCharacterStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateNCharacterStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateAsciiStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream(1, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateBinaryStream("t1", null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null, null, 0), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject(1, null, null), NOT_SUPPORTED);
+    Common.assertThrowsContains(ns, () -> rs.updateObject("t1", null, null), NOT_SUPPORTED);
+  }
+
+  @Test
+  public void notSupported() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Common.assertThrowsContains(ns, () -> rs.getRowId(1), "RowId are not supported");
+    Common.assertThrowsContains(ns, () -> rs.getRowId("t1"), "RowId are not supported");
+    Map<String, Class<?>> map = new HashMap<>();
+    map.put("ddd", Integer.class);
+    Common.assertThrowsContains(
+        ns,
+        () -> rs.getObject(1, map),
+        "Method ResultSet.getObject(int columnIndex, Map<String, Class<?>> map) not supported");
+    Common.assertThrowsContains(
+        ns,
+        () -> rs.getObject("t1", map),
+        "Method ResultSet.getObject(String columnLabel, Map<String, Class<?>> map) not supported");
+    Common.assertThrowsContains(ns, rs::getCursorName, "Cursors are not supported");
+  }
+
+  @Test
+  public void staticMethod() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Assertions.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, rs.getHoldability());
+    rs.unwrap(ResultSet.class);
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.unwrap(String.class),
+        "The receiver is not a wrapper for java.lang.String");
+
+    assertEquals(ResultSet.FETCH_UNKNOWN, rs.getFetchDirection());
+    rs.setFetchDirection(ResultSet.FETCH_UNKNOWN);
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.setFetchDirection(ResultSet.FETCH_REVERSE),
+        "Invalid operation");
+    assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency());
+  }
+
+  @Test
+  public void type() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertEquals(ResultSet.TYPE_FORWARD_ONLY, rs.getType());
+    assertEquals(stmt, rs.getStatement());
+
+    stmt = sharedConn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertEquals(ResultSet.TYPE_SCROLL_SENSITIVE, rs.getType());
+    assertEquals(stmt, rs.getStatement());
+  }
+
+  @Test
+  public void wrongIndex() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.next();
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(-1),
+        "Wrong index position. Is -1 but must be in 1-2 range");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.getObject(10),
+        "Wrong index position. Is 10 but must be in 1-2 range");
+    Common.assertThrowsContains(
+        SQLException.class, () -> rs.findColumn(null), "null is not a valid label value");
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rs.findColumn("yy"),
+        "Unknown label 'yy'. Possible value [resultsettest.t1, t1, resultsettest.t2, t2]");
+  }
+
+  @Test
+  public void isBeforeFirstFetchTest() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(1);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.isBeforeFirst());
+    while (rs.next()) {
+      assertFalse(rs.isBeforeFirst());
+    }
+    assertFalse(rs.isBeforeFirst());
+    rs.close();
+    Common.assertThrowsContains(
+        SQLException.class, rs::isBeforeFirst, "Operation not permit on a closed resultSet");
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/resultset/ResultSetMetadataTest.java b/src/test/java/org/mariadb/jdbc/integration/resultset/ResultSetMetadataTest.java
new file mode 100644
index 0000000..cee1a77
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/resultset/ResultSetMetadataTest.java
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.resultset;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.*;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class ResultSetMetadataTest extends Common {
+
+  private static final Class<? extends java.lang.Exception> sqle = SQLException.class;
+
+  @AfterAll
+  public static void dropAll() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS ResultSetTest");
+    stmt.execute("DROP TABLE IF EXISTS test_rsmd");
+    stmt.execute("DROP TABLE IF EXISTS resultsetmetadatatest1");
+    stmt.execute("DROP TABLE IF EXISTS resultsetmetadatatest2");
+    stmt.execute("DROP TABLE IF EXISTS resultsetmetadatatest3");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    dropAll();
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("CREATE TABLE ResultSetTest (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("INSERT INTO ResultSetTest(t2) values (1),(2),(3),(4),(5),(6),(7),(8)");
+    stmt.execute(
+        "CREATE TABLE test_rsmd(id_col int not null primary key auto_increment, nullable_col"
+            + " varchar(20), unikey_col int unique, char_col char(10), us smallint unsigned)");
+    stmt.execute("CREATE TABLE resultsetmetadatatest1(id int, name varchar(20))");
+    stmt.execute("CREATE TABLE resultsetmetadatatest2(id int, name varchar(20))");
+    stmt.execute("CREATE TABLE resultsetmetadatatest3(id int, name varchar(20))");
+  }
+
+  @Test
+  public void metaDataTest() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("insert into test_rsmd (id_col,nullable_col,unikey_col) values (null, 'hej', 9)");
+    ResultSet rs =
+        stmt.executeQuery(
+            "select id_col, nullable_col, unikey_col as something, char_col,us from test_rsmd");
+    assertTrue(rs.next());
+    ResultSetMetaData rsmd = rs.getMetaData();
+    if (!isXpand()) {
+      assertTrue(rsmd.isAutoIncrement(1));
+      assertFalse(rsmd.isAutoIncrement(2));
+    }
+    assertEquals(5, rsmd.getColumnCount());
+    assertEquals(ResultSetMetaData.columnNullable, rsmd.isNullable(2));
+    assertEquals(ResultSetMetaData.columnNoNulls, rsmd.isNullable(1));
+    assertEquals(String.class.getName(), rsmd.getColumnClassName(2));
+    assertEquals(Integer.class.getName(), rsmd.getColumnClassName(1));
+    assertEquals(Integer.class.getName(), rsmd.getColumnClassName(3));
+    assertEquals("id_col", rsmd.getColumnLabel(1));
+    assertEquals("nullable_col", rsmd.getColumnLabel(2));
+    assertEquals("something", rsmd.getColumnLabel(3));
+    assertEquals("unikey_col", rsmd.getColumnName(3));
+    if (!isXpand()) {
+      assertEquals(Types.CHAR, rsmd.getColumnType(4));
+    }
+    assertEquals(Types.INTEGER, rsmd.getColumnType(5));
+    assertFalse(rsmd.isReadOnly(1));
+    assertFalse(rsmd.isReadOnly(2));
+    assertTrue(rsmd.isWritable(1));
+    assertTrue(rsmd.isDefinitelyWritable(1));
+    assertTrue(rsmd.isCaseSensitive(1));
+    assertTrue(rsmd.isSearchable(1));
+    assertFalse(rsmd.isCurrency(1));
+    assertTrue(rsmd.isSigned(3));
+    assertFalse(rsmd.isSigned(5));
+
+    Common.assertThrowsContains(sqle, () -> rsmd.isAutoIncrement(6), "wrong column index 6");
+    Common.assertThrowsContains(sqle, () -> rsmd.isReadOnly(6), "wrong column index 6");
+    Common.assertThrowsContains(sqle, () -> rsmd.isReadOnly(-6), "wrong column index -6");
+    Common.assertThrowsContains(sqle, () -> rsmd.isWritable(6), "wrong column index 6");
+    Common.assertThrowsContains(sqle, () -> rsmd.isDefinitelyWritable(6), "wrong column index 6");
+
+    DatabaseMetaData md = sharedConn.getMetaData();
+    ResultSet cols = md.getColumns(null, null, "test\\_rsmd", null);
+    cols.next();
+    assertEquals("id_col", cols.getString("COLUMN_NAME"));
+    assertEquals(Types.INTEGER, cols.getInt("DATA_TYPE"));
+    cols.next(); /* nullable_col */
+    cols.next(); /* unikey_col */
+    cols.next(); /* char_col */
+    assertEquals("char_col", cols.getString("COLUMN_NAME"));
+    assertEquals(Types.CHAR, cols.getInt("DATA_TYPE"));
+    cols.next(); /* us */ // CONJ-96: SMALLINT UNSIGNED gives Types.SMALLINT
+    assertEquals("us", cols.getString("COLUMN_NAME"));
+    assertEquals(Types.SMALLINT, cols.getInt("DATA_TYPE"));
+
+    rs = stmt.executeQuery("select 1 from test_rsmd");
+    ResultSetMetaData rsmd2 = rs.getMetaData();
+    assertTrue(rsmd2.isReadOnly(1));
+    assertFalse(rsmd2.isWritable(1));
+    assertFalse(rsmd2.isDefinitelyWritable(1));
+  }
+
+  @Test
+  public void conj17() throws Exception {
+    ResultSet rs =
+        sharedConn
+            .createStatement()
+            .executeQuery("select count(*),1 from information_schema.tables");
+    assertTrue(rs.next());
+    assertEquals(rs.getMetaData().getColumnName(1), "count(*)");
+    assertEquals(rs.getMetaData().getColumnName(2), "1");
+  }
+
+  @Test
+  public void conj84() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("INSERT INTO resultsetmetadatatest1 VALUES (1, 'foo')");
+    stmt.execute("INSERT INTO resultsetmetadatatest2 VALUES (2, 'bar')");
+    ResultSet rs =
+        sharedConn
+            .createStatement()
+            .executeQuery(
+                "select resultsetmetadatatest1.*, resultsetmetadatatest2.* FROM"
+                    + " resultsetmetadatatest1 join resultsetmetadatatest2");
+    assertTrue(rs.next());
+    assertEquals(rs.findColumn("id"), 1);
+    assertEquals(rs.findColumn("name"), 2);
+    assertEquals(rs.findColumn("resultsetmetadatatest1.id"), 1);
+    assertEquals(rs.findColumn("resultsetmetadatatest1.name"), 2);
+    assertEquals(rs.findColumn("resultsetmetadatatest2.id"), 3);
+    assertEquals(rs.findColumn("resultsetmetadatatest2.name"), 4);
+  }
+
+  @Test
+  public void testAlias() throws Exception {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS testAlias");
+    stmt.execute("DROP TABLE IF EXISTS testAlias2");
+    stmt.execute("CREATE TABLE testAlias(id int, name varchar(20))");
+    stmt.execute("CREATE TABLE testAlias2(id2 int, name2 varchar(20))");
+
+    stmt.execute("INSERT INTO testAlias VALUES (1, 'foo')");
+    stmt.execute("INSERT INTO testAlias2 VALUES (2, 'bar')");
+    ResultSet rs =
+        sharedConn
+            .createStatement()
+            .executeQuery(
+                "select alias1.id as idalias1, "
+                    + "alias1.name as namealias1, "
+                    + "id2 as idalias2, "
+                    + "name2, "
+                    + "testAlias.id,"
+                    + "alias1.id "
+                    + "FROM testAlias as alias1 "
+                    + "join testAlias2 as alias2 "
+                    + "join testAlias");
+    assertTrue(rs.next());
+
+    assertEquals(rs.findColumn("idalias1"), 1);
+    assertEquals(rs.findColumn("alias1.idalias1"), 1);
+
+    Common.assertThrowsContains(sqle, () -> rs.findColumn("name"), "Unknown label 'name'");
+    assertEquals(rs.findColumn("namealias1"), 2);
+    assertEquals(rs.findColumn("alias1.namealias1"), 2);
+
+    Common.assertThrowsContains(sqle, () -> rs.findColumn("id2"), "Unknown label 'id2'");
+    assertEquals(rs.findColumn("idalias2"), 3);
+    assertEquals(rs.findColumn("alias2.idalias2"), 3);
+    Common.assertThrowsContains(
+        sqle, () -> rs.findColumn("testAlias2.id2"), "Unknown label 'testAlias2.id2'");
+
+    assertEquals(rs.findColumn("name2"), 4);
+    Common.assertThrowsContains(
+        sqle, () -> rs.findColumn("testAlias2.name2"), "Unknown label 'testAlias2.name2'");
+    assertEquals(rs.findColumn("alias2.name2"), 4);
+
+    assertEquals(rs.findColumn("id"), 5);
+    assertEquals(rs.findColumn("testAlias.id"), 5);
+    assertEquals(rs.findColumn("alias1.id"), 6);
+
+    Common.assertThrowsContains(
+        sqle, () -> rs.findColumn("alias2.name22"), "Unknown label 'alias2.name22'");
+    Common.assertThrowsContains(sqle, () -> rs.findColumn(""), "Unknown label ''");
+    Common.assertThrowsContains(sqle, () -> rs.findColumn(null), "null is not a valid label value");
+  }
+
+  @Test
+  public void blankTableNameMeta() throws Exception {
+    ResultSet rs =
+        sharedConn
+            .createStatement()
+            .executeQuery(
+                "SELECT id AS id_alias FROM resultsetmetadatatest3 AS"
+                    + " resultsetmetadatatest1_alias");
+    ResultSetMetaData rsmd = rs.getMetaData();
+
+    assertEquals("resultsetmetadatatest3", rsmd.getTableName(1));
+    assertEquals(rsmd.getColumnLabel(1), "id_alias");
+    assertEquals(rsmd.getColumnName(1), "id");
+
+    try (Connection connection = createCon("&blankTableNameMeta")) {
+      rs =
+          connection
+              .createStatement()
+              .executeQuery(
+                  "SELECT id AS id_alias FROM resultsetmetadatatest3 AS"
+                      + " resultsetmetadatatest1_alias");
+      rsmd = rs.getMetaData();
+
+      assertEquals("", rsmd.getTableName(1));
+      assertEquals("id_alias", rsmd.getColumnLabel(1));
+      assertEquals("id", rsmd.getColumnName(1));
+    }
+  }
+
+  @Test
+  public void staticMethod() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM resultsetmetadatatest3");
+    ResultSetMetaData rsmd = rs.getMetaData();
+
+    rsmd.unwrap(org.mariadb.jdbc.client.result.ResultSetMetaData.class);
+
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> rsmd.unwrap(String.class),
+        "The receiver is not a wrapper for java.lang.String");
+  }
+
+  @Test
+  public void databaseResultsetMeta() throws SQLException {
+    DatabaseMetaData meta = sharedConn.getMetaData();
+    ResultSet rs = meta.getTableTypes();
+    assertTrue(rs.next());
+    ResultSetMetaData rsMeta = rs.getMetaData();
+    assertEquals("TABLE_TYPE", rsMeta.getColumnName(1));
+    assertEquals("", rsMeta.getTableName(1));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/resultset/RowChangeTest.java b/src/test/java/org/mariadb/jdbc/integration/resultset/RowChangeTest.java
new file mode 100644
index 0000000..f22c9c1
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/resultset/RowChangeTest.java
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.resultset;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class RowChangeTest extends Common {
+
+  @AfterAll
+  public static void after2() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE ResultSetTest");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS ResultSetTest");
+    stmt.execute("CREATE TABLE ResultSetTest (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("INSERT INTO ResultSetTest(t2) values (1),(2),(3),(4),(5),(6),(7),(8)");
+  }
+
+  @Test
+  public void next() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void isAfterLast() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertFalse(rs.isAfterLast());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.isAfterLast());
+    assertFalse(rs.next());
+    assertTrue(rs.isAfterLast());
+  }
+
+  @Test
+  public void isFirst() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.isFirst());
+    assertTrue(rs.next());
+    assertTrue(rs.isFirst());
+    while (rs.next()) {
+      assertFalse(rs.isFirst());
+    }
+    assertFalse(rs.isFirst());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest where t1 = -1");
+    assertFalse(rs.isFirst());
+    assertFalse(rs.next());
+    assertFalse(rs.isFirst());
+  }
+
+  @Test
+  public void isLast() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.isLast());
+    for (int i = 1; i < 8; i++) {
+      assertTrue(rs.next());
+      assertFalse(rs.isLast());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertTrue(rs.next());
+    assertEquals(8, rs.getInt(1));
+    assertTrue(rs.isLast());
+    assertFalse(rs.next());
+    assertFalse(rs.isLast());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest where t1 = -1");
+    assertFalse(rs.isLast());
+    assertFalse(rs.next());
+    assertFalse(rs.isLast());
+  }
+
+  @Test
+  public void isBeforeFirst() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.isBeforeFirst());
+    while (rs.next()) {
+      assertFalse(rs.isBeforeFirst());
+    }
+    assertFalse(rs.isBeforeFirst());
+  }
+
+  @Test
+  public void beforeFirst() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.isBeforeFirst());
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+    assertFalse(rs.isBeforeFirst());
+    rs.beforeFirst();
+    assertTrue(rs.isBeforeFirst());
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest where t1 = -1");
+    assertFalse(rs.isBeforeFirst());
+  }
+
+  @Test
+  public void afterLast() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.afterLast();
+    assertFalse(rs.next());
+    assertTrue(rs.previous());
+    assertEquals(8, rs.getInt(1));
+  }
+
+  @Test
+  public void first() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.afterLast();
+    assertTrue(rs.first());
+    assertEquals(1, rs.getInt(1));
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 = -1");
+    assertFalse(rs.first());
+  }
+
+  @Test
+  public void last() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.last());
+    assertEquals(8, rs.getInt(1));
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 = -1");
+    assertFalse(rs.last());
+  }
+
+  @Test
+  public void getRow() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertEquals(0, rs.getRow());
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getRow());
+    }
+    assertFalse(rs.next());
+    assertEquals(0, rs.getRow());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 = -1");
+    assertEquals(0, rs.getRow());
+    assertFalse(rs.next());
+    assertEquals(0, rs.getRow());
+  }
+
+  @Test
+  public void absolute() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.absolute(0));
+    assertFalse(rs.absolute(9));
+    assertTrue(rs.absolute(4));
+    assertEquals(4, rs.getRow());
+    assertTrue(rs.absolute(5));
+    assertEquals(5, rs.getRow());
+    assertFalse(rs.absolute(9));
+    assertTrue(rs.isAfterLast());
+    assertTrue(rs.absolute(1));
+    assertTrue(rs.isFirst());
+
+    assertFalse(rs.absolute(-9));
+    assertFalse(rs.isAfterLast());
+    assertTrue(rs.isBeforeFirst());
+    assertTrue(rs.absolute(-8));
+    assertTrue(rs.isFirst());
+    assertTrue(rs.absolute(-3));
+    assertEquals(6, rs.getInt(1));
+  }
+
+  @Test
+  public void relative() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.relative(2);
+    assertEquals(2, rs.getInt(1));
+    rs.relative(2);
+    assertEquals(4, rs.getInt(1));
+    rs.relative(10);
+    assertTrue(rs.isAfterLast());
+    rs.relative(-20);
+    assertTrue(rs.isBeforeFirst());
+    rs.relative(5);
+    assertEquals(5, rs.getInt(1));
+  }
+
+  @Test
+  public void previous() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.afterLast();
+    for (int i = 8; i > 0; i--) {
+      assertTrue(rs.previous());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.previous());
+    assertFalse(rs.previous());
+  }
+
+  @Test
+  public void getFetchSize() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertEquals(0, rs.getFetchSize());
+    rs.setFetchSize(0);
+    assertEquals(0, rs.getFetchSize());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/resultset/StreamingRowChangeTest.java b/src/test/java/org/mariadb/jdbc/integration/resultset/StreamingRowChangeTest.java
new file mode 100644
index 0000000..a83faf9
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/resultset/StreamingRowChangeTest.java
@@ -0,0 +1,477 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.resultset;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Statement;
+import org.mariadb.jdbc.integration.Common;
+
+public class StreamingRowChangeTest extends Common {
+
+  private final String NOT_FORWARD = "Operation not permit on TYPE_FORWARD_ONLY resultSet";
+  private final Class<? extends java.lang.Exception> sqle = SQLException.class;
+
+  @AfterAll
+  public static void after2() throws SQLException {
+    sharedConn.createStatement().execute("DROP TABLE ResultSetTest");
+  }
+
+  @BeforeAll
+  public static void beforeAll2() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.execute("DROP TABLE IF EXISTS ResultSetTest");
+    stmt.execute("CREATE TABLE ResultSetTest (t1 int not null primary key auto_increment, t2 int)");
+    stmt.execute("INSERT INTO ResultSetTest(t2) values (1),(2),(3),(4),(5),(6),(7),(8)");
+  }
+
+  @Test
+  public void closedRes() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.close();
+    String NOT_SUPPORTED = "Operation not permit on a closed resultSet";
+    Common.assertThrowsContains(sqle, rs::next, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::isBeforeFirst, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::isAfterLast, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::isFirst, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::isLast, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::beforeFirst, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::afterLast, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::first, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::last, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::getRow, NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, () -> rs.absolute(0), NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, () -> rs.relative(1), NOT_SUPPORTED);
+    Common.assertThrowsContains(sqle, rs::previous, NOT_SUPPORTED);
+  }
+
+  @Test
+  public void next() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+
+    // next fetching no result
+    stmt.setFetchSize(8);
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+
+    // next fetching no result keeping all results
+    stmt = sharedConn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    stmt.setFetchSize(8);
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+  }
+
+  @Test
+  public void isAfterLast() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    isAfterLast(stmt);
+    stmt.setFetchSize(3);
+    isAfterLast(stmt);
+    stmt.setFetchSize(4);
+    isAfterLast(stmt);
+  }
+
+  public void isAfterLast(Statement stmt) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertFalse(rs.isAfterLast());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.isAfterLast());
+    assertFalse(rs.next());
+    assertTrue(rs.isAfterLast());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 < 0");
+    assertFalse(rs.isAfterLast());
+    assertFalse(rs.next());
+    assertFalse(rs.isAfterLast());
+  }
+
+  @Test
+  public void isFirst() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    Statement stmt2 =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    isFirst(stmt, stmt2);
+
+    stmt.setFetchSize(3);
+    stmt2.setFetchSize(3);
+    isFirst(stmt, stmt2);
+
+    stmt.setFetchSize(4);
+    stmt2.setFetchSize(4);
+    isFirst(stmt, stmt2);
+  }
+
+  private void isFirst(Statement stmt, Statement stmt2) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.isFirst());
+    assertTrue(rs.next());
+    assertTrue(rs.isFirst());
+    while (rs.next()) {
+      assertFalse(rs.isFirst());
+    }
+    assertFalse(rs.isFirst());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest Where 1 = -1");
+    assertFalse(rs.isFirst());
+    assertFalse(rs.next());
+    assertFalse(rs.isFirst());
+
+    rs = stmt2.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.isFirst());
+    assertTrue(rs.next());
+    assertTrue(rs.isFirst());
+    while (rs.next()) {
+      assertFalse(rs.isFirst());
+    }
+    assertFalse(rs.isFirst());
+
+    rs = stmt2.executeQuery("SELECT * FROM ResultSetTest Where 1 = -1");
+    assertFalse(rs.isFirst());
+    assertFalse(rs.next());
+    assertFalse(rs.isFirst());
+  }
+
+  @Test
+  public void isLast() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    isLast(stmt);
+    stmt.setFetchSize(3);
+    isLast(stmt);
+    stmt.setFetchSize(4);
+    isLast(stmt);
+  }
+
+  private void isLast(Statement stmt) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.isLast());
+    for (int i = 1; i < 8; i++) {
+      assertTrue(rs.next());
+      assertFalse(rs.isLast());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertTrue(rs.next());
+    assertEquals(8, rs.getInt(1));
+    assertTrue(rs.isLast());
+    assertFalse(rs.next());
+    assertFalse(rs.isLast());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest Where 1 = -1");
+    rs.isLast();
+    assertFalse(rs.isLast());
+    assertFalse(rs.next());
+    assertFalse(rs.isLast());
+
+    stmt = sharedConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+    stmt.setFetchSize(3);
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.isLast());
+    for (int i = 1; i < 8; i++) {
+      assertTrue(rs.next());
+      assertFalse(rs.isLast());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertTrue(rs.next());
+    assertEquals(8, rs.getInt(1));
+    assertTrue(rs.isLast());
+    assertFalse(rs.next());
+    assertFalse(rs.isLast());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest Where 1 = -1");
+    assertFalse(rs.isLast());
+    assertFalse(rs.next());
+    assertFalse(rs.isLast());
+  }
+
+  @Test
+  public void isBeforeFirst() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    isBeforeFirst(stmt);
+    stmt.setFetchSize(3);
+    isBeforeFirst(stmt);
+  }
+
+  private void isBeforeFirst(Statement stmt) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.isBeforeFirst());
+    while (rs.next()) {
+      assertFalse(rs.isBeforeFirst());
+    }
+    assertFalse(rs.isBeforeFirst());
+
+    stmt = sharedConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+    stmt.setFetchSize(3);
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.isBeforeFirst());
+    while (rs.next()) {
+      assertFalse(rs.isBeforeFirst());
+    }
+    assertFalse(rs.isBeforeFirst());
+  }
+
+  @Test
+  public void beforeFirst() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    beforeFirst(stmt);
+    stmt.setFetchSize(3);
+    beforeFirst(stmt);
+  }
+
+  private void beforeFirst(Statement stmt) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+    assertFalse(rs.isBeforeFirst());
+    rs.beforeFirst();
+    assertTrue(rs.isBeforeFirst());
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+
+    stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs2 = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Common.assertThrowsContains(sqle, rs2::beforeFirst, NOT_FORWARD);
+  }
+
+  @Test
+  public void afterLast() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    afterLast(stmt);
+    stmt.setFetchSize(3);
+    afterLast(stmt);
+  }
+
+  private void afterLast(Statement stmt) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.afterLast();
+    assertFalse(rs.next());
+    assertTrue(rs.previous());
+    assertEquals(8, rs.getInt(1));
+
+    stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs2 = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Common.assertThrowsContains(sqle, rs2::afterLast, NOT_FORWARD);
+  }
+
+  @Test
+  public void first() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    first(stmt);
+    stmt.setFetchSize(3);
+    first(stmt);
+  }
+
+  private void first(Statement stmt) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.afterLast();
+    assertTrue(rs.first());
+    assertEquals(1, rs.getInt(1));
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 = -1");
+    assertFalse(rs.first());
+
+    stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs2 = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Common.assertThrowsContains(sqle, rs2::first, NOT_FORWARD);
+  }
+
+  @Test
+  public void last() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    last(stmt);
+    stmt.setFetchSize(3);
+    last(stmt);
+  }
+
+  private void last(Statement stmt) throws SQLException {
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.last());
+    assertEquals(8, rs.getInt(1));
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 = -1");
+    assertFalse(rs.last());
+
+    stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertTrue(rs.last());
+    assertEquals(8, rs.getInt(1));
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 = -1");
+    assertFalse(rs.last());
+  }
+
+  @Test
+  public void getRow() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertEquals(0, rs.getRow());
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(0, rs.getRow());
+    }
+    assertFalse(rs.next());
+    assertEquals(0, rs.getRow());
+
+    rs = stmt.executeQuery("SELECT * FROM ResultSetTest WHERE t1 = -1");
+    assertEquals(0, rs.getRow());
+    assertFalse(rs.next());
+    assertEquals(0, rs.getRow());
+  }
+
+  @Test
+  public void absolute() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    stmt.setFetchSize(3);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.absolute(0));
+    assertTrue(rs.absolute(2));
+    assertEquals(2, rs.getRow());
+    assertEquals(2, rs.getInt(1));
+    assertTrue(rs.absolute(6));
+    assertEquals(6, rs.getRow());
+    assertEquals(6, rs.getInt(1));
+    assertFalse(rs.absolute(9));
+    assertTrue(rs.absolute(4));
+    assertEquals(4, rs.getRow());
+    assertEquals(4, rs.getInt(1));
+    assertTrue(rs.absolute(5));
+    assertEquals(5, rs.getRow());
+    assertEquals(5, rs.getInt(1));
+    assertFalse(rs.absolute(9));
+    assertTrue(rs.isAfterLast());
+    assertTrue(rs.absolute(1));
+    assertTrue(rs.isFirst());
+
+    assertFalse(rs.absolute(-9));
+    assertFalse(rs.isAfterLast());
+    assertTrue(rs.absolute(-8));
+    assertTrue(rs.isFirst());
+    assertTrue(rs.absolute(-3));
+    assertEquals(6, rs.getInt(1));
+
+    stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs2 = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Common.assertThrowsContains(sqle, () -> rs2.absolute(0), NOT_FORWARD);
+  }
+
+  @Test
+  public void relative() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    stmt.setFetchSize(3);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    rs.relative(2);
+    assertEquals(2, rs.getInt(1));
+    rs.relative(2);
+    assertEquals(4, rs.getInt(1));
+    rs.relative(10);
+    assertTrue(rs.isAfterLast());
+    rs.relative(-20);
+    assertTrue(rs.isBeforeFirst());
+    rs.relative(5);
+    assertEquals(5, rs.getInt(1));
+
+    stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs2 = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Common.assertThrowsContains(sqle, () -> rs2.relative(0), NOT_FORWARD);
+  }
+
+  @Test
+  public void previous() throws SQLException {
+    Statement stmt =
+        sharedConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+    stmt.setFetchSize(3);
+    ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertFalse(rs.previous());
+    rs.afterLast();
+    for (int i = 8; i > 0; i--) {
+      assertTrue(rs.previous());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.previous());
+
+    stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs2 = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    Common.assertThrowsContains(sqle, rs2::previous, NOT_FORWARD);
+  }
+
+  @Test
+  public void getFetchSize() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertEquals(3, rs.getFetchSize());
+
+    assertTrue(rs.next());
+    assertEquals(1, rs.getInt(1));
+    assertTrue(rs.next());
+    assertEquals(2, rs.getInt(1));
+
+    rs.setFetchSize(2);
+    assertEquals(2, rs.getFetchSize());
+
+    for (int i = 3; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+    Common.assertThrowsContains(sqle, () -> rs.setFetchSize(-2), "invalid fetch size -2");
+  }
+
+  @Test
+  public void removeStreaming() throws SQLException {
+    Statement stmt = sharedConn.createStatement();
+    stmt.setFetchSize(3);
+    final ResultSet rs = stmt.executeQuery("SELECT * FROM ResultSetTest");
+    assertEquals(3, rs.getFetchSize());
+    rs.setFetchSize(0);
+    assertEquals(0, rs.getFetchSize());
+
+    for (int i = 1; i < 9; i++) {
+      assertTrue(rs.next());
+      assertEquals(i, rs.getInt(1));
+    }
+    assertFalse(rs.next());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/tools/TcpProxy.java b/src/test/java/org/mariadb/jdbc/integration/tools/TcpProxy.java
new file mode 100644
index 0000000..56032fd
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/tools/TcpProxy.java
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.tools;
+
+import java.io.IOException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+public class TcpProxy {
+  private static final Logger logger = Loggers.getLogger(TcpProxy.class);
+
+  private final String host;
+  private final TcpProxySocket socket;
+
+  /**
+   * Initialise proxy.
+   *
+   * @param host host (ip / dns)
+   * @param remoteport port
+   * @throws IOException exception
+   */
+  public TcpProxy(String host, int remoteport) throws IOException {
+    this.host = host;
+    socket = new TcpProxySocket(host, remoteport);
+    Executors.newSingleThreadScheduledExecutor().schedule(socket, 0, TimeUnit.MILLISECONDS);
+  }
+
+  public void stop() {
+    socket.kill();
+  }
+
+  public void setDelay(int delay) {
+    socket.setDelay(delay);
+  }
+
+  public void removeDelay() {
+    socket.setDelay(1);
+  }
+
+  /**
+   * Stop proxy and restart after X milliseconds.
+   *
+   * @param sleepTime sleep time in milliseconds
+   */
+  public void restart(long sleepTime) {
+    socket.kill();
+    logger.trace("host proxy port " + socket.getLocalport() + " for " + host + " started");
+    Executors.newSingleThreadScheduledExecutor().schedule(socket, sleepTime, TimeUnit.MILLISECONDS);
+  }
+
+  public void forceClose() {
+    socket.sendRst();
+  }
+
+  /** Restart proxy. */
+  public void restart() {
+    Executors.newSingleThreadExecutor().execute(socket);
+    try {
+      Thread.sleep(10);
+    } catch (InterruptedException e) {
+      // eat Exception
+    }
+  }
+
+  public int getLocalPort() {
+    return socket.getLocalPort();
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/tools/TcpProxySocket.java b/src/test/java/org/mariadb/jdbc/integration/tools/TcpProxySocket.java
new file mode 100644
index 0000000..33367c0
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/tools/TcpProxySocket.java
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.tools;
+
+import java.io.*;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+
+public class TcpProxySocket implements Runnable {
+  private static final Logger logger = Loggers.getLogger(TcpProxySocket.class);
+
+  private final String host;
+  private final int remoteport;
+  private final int localport;
+  private boolean stop = false;
+  private Socket client = null;
+  private Socket server = null;
+  private ServerSocket ss;
+  private int delay;
+
+  /**
+   * Creation of proxy.
+   *
+   * @param host database host
+   * @param remoteport database port
+   * @throws IOException exception
+   */
+  public TcpProxySocket(String host, int remoteport) throws IOException {
+    this.host = host;
+    this.remoteport = remoteport;
+    ss = new ServerSocket(0);
+    this.localport = ss.getLocalPort();
+  }
+
+  public int getLocalPort() {
+    return ss.getLocalPort();
+  }
+
+  public boolean isClosed() {
+    return ss.isClosed();
+  }
+
+  public void setDelay(int delay) {
+    this.delay = delay;
+  }
+
+  /** Kill proxy. */
+  public void kill() {
+    stop = true;
+    try {
+      if (server != null) {
+        server.close();
+      }
+    } catch (IOException e) {
+      // eat Exception
+    }
+    try {
+      if (client != null) {
+        client.close();
+      }
+    } catch (IOException e) {
+      // eat Exception
+    }
+    try {
+      ss.close();
+    } catch (IOException e) {
+      // eat Exception
+    }
+  }
+
+  public void sendRst() {
+
+    try {
+      if (client != null) {
+        // send an RST, not FIN
+        client.setSoLinger(true, 0);
+        client.close();
+      }
+    } catch (IOException e) {
+      // eat Exception
+    }
+    try {
+      if (server != null) {
+        server.close();
+      }
+    } catch (IOException e) {
+      // eat Exception
+    }
+
+    try {
+      ss.close();
+    } catch (IOException e) {
+      // eat Exception
+    }
+  }
+
+  @Override
+  public void run() {
+
+    logger.trace("host proxy port " + this.localport + " for " + host + " started");
+    stop = false;
+    try {
+      try {
+        if (ss.isClosed()) {
+          ss = new ServerSocket(localport);
+        }
+      } catch (BindException b) {
+        // in case for testing crash and reopen too quickly
+        try {
+          Thread.sleep(100);
+        } catch (InterruptedException i) {
+          // eat Exception
+        }
+        if (ss.isClosed()) {
+          ss = new ServerSocket(localport);
+        }
+      }
+      final byte[] request = new byte[1024];
+      byte[] reply = new byte[4096];
+      while (!stop) {
+        try {
+          client = ss.accept();
+          final InputStream fromClient = client.getInputStream();
+          final OutputStream toClient = client.getOutputStream();
+          try {
+            server = new Socket(host, remoteport);
+          } catch (IOException e) {
+            PrintWriter out = new PrintWriter(new OutputStreamWriter(toClient));
+            out.println("Proxy server cannot connect to " + host + ":" + remoteport + ":\n" + e);
+            out.flush();
+            client.close();
+            continue;
+          }
+          final InputStream fromServer = server.getInputStream();
+          final OutputStream toServer = server.getOutputStream();
+          new Thread(
+                  () -> {
+                    int bytesRead;
+                    try {
+                      while ((bytesRead = fromClient.read(request)) != -1) {
+                        if (delay > 0) {
+                          try {
+                            Thread.sleep(delay);
+                          } catch (InterruptedException e) {
+                            e.printStackTrace();
+                          }
+                        }
+                        toServer.write(request, 0, bytesRead);
+                        toServer.flush();
+                      }
+                    } catch (IOException e) {
+                      // eat exception
+                    }
+                    try {
+                      toServer.close();
+                    } catch (IOException e) {
+                      // eat exception
+                    }
+                  })
+              .start();
+          int bytesRead;
+          try {
+            while ((bytesRead = fromServer.read(reply)) != -1) {
+              try {
+                Thread.sleep(1);
+              } catch (InterruptedException e) {
+                e.printStackTrace();
+              }
+              toClient.write(reply, 0, bytesRead);
+              toClient.flush();
+            }
+          } catch (IOException e) {
+            // eat exception
+          }
+          toClient.close();
+        } catch (IOException e) {
+          // System.err.println("ERROR socket : "+e);
+        } finally {
+          try {
+            if (server != null) {
+              server.close();
+            }
+            if (client != null) {
+              client.close();
+            }
+          } catch (IOException e) {
+            // eat exception
+          }
+        }
+      }
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  public int getLocalport() {
+    return localport;
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/util/Env2CredentialPlugin.java b/src/test/java/org/mariadb/jdbc/integration/util/Env2CredentialPlugin.java
new file mode 100644
index 0000000..bc26e52
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/util/Env2CredentialPlugin.java
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.util;
+
+import org.mariadb.jdbc.plugin.Credential;
+import org.mariadb.jdbc.plugin.CredentialPlugin;
+
+/**
+ * Authentication using environment variable.
+ *
+ * <p>default implementation use environment variable MARIADB_USER and MARIADB_PWD
+ *
+ * <p>example : `jdbc:mariadb://host/db?credentialType=ENV`
+ *
+ * <p>2 options `userKey` and `pwdKey` permits indicating which environment variable to use.
+ */
+public class Env2CredentialPlugin implements CredentialPlugin {
+
+  @Override
+  public String type() {
+    return "ENVTEST";
+  }
+
+  @Override
+  public boolean mustUseSsl() {
+    return true;
+  }
+
+  @Override
+  public String defaultAuthenticationPluginType() {
+    return "mysql_native_password";
+  }
+
+  @Override
+  public Credential get() {
+    return new Credential(System.getenv("MARIADB2_USER"), System.getenv("MARIADB2_PWD"));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/util/SocketFactoryBasicTest.java b/src/test/java/org/mariadb/jdbc/integration/util/SocketFactoryBasicTest.java
new file mode 100644
index 0000000..adc80c7
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/util/SocketFactoryBasicTest.java
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.util;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import javax.net.SocketFactory;
+
+public class SocketFactoryBasicTest extends SocketFactory {
+  final SocketFactory socketFactory = SocketFactory.getDefault();
+
+  public SocketFactoryBasicTest() {}
+
+  @Override
+  public Socket createSocket() throws IOException {
+    return socketFactory.createSocket();
+  }
+
+  @Override
+  public Socket createSocket(String s, int i) throws IOException {
+    return socketFactory.createSocket(s, i);
+  }
+
+  @Override
+  public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException {
+    return socketFactory.createSocket(s, i, inetAddress, i1);
+  }
+
+  @Override
+  public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
+    return socketFactory.createSocket(inetAddress, i);
+  }
+
+  @Override
+  public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1)
+      throws IOException {
+    return socketFactory.createSocket(inetAddress, i, inetAddress1, i1);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/integration/util/SocketFactoryTest.java b/src/test/java/org/mariadb/jdbc/integration/util/SocketFactoryTest.java
new file mode 100644
index 0000000..1f94f8a
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/integration/util/SocketFactoryTest.java
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.integration.util;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import javax.net.SocketFactory;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.util.ConfigurableSocketFactory;
+
+public class SocketFactoryTest extends ConfigurableSocketFactory {
+  final SocketFactory socketFactory = SocketFactory.getDefault();
+
+  public SocketFactoryTest() {}
+
+  @Override
+  public void setConfiguration(Configuration conf, String host) {}
+
+  @Override
+  public Socket createSocket() throws IOException {
+    return socketFactory.createSocket();
+  }
+
+  @Override
+  public Socket createSocket(String s, int i) throws IOException {
+    return socketFactory.createSocket(s, i);
+  }
+
+  @Override
+  public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException {
+    return socketFactory.createSocket(s, i, inetAddress, i1);
+  }
+
+  @Override
+  public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
+    return socketFactory.createSocket(inetAddress, i);
+  }
+
+  @Override
+  public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1)
+      throws IOException {
+    return socketFactory.createSocket(inetAddress, i, inetAddress1, i1);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/client/HostnameVerifierTest.java b/src/test/java/org/mariadb/jdbc/unit/client/HostnameVerifierTest.java
new file mode 100644
index 0000000..e8958b6
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/client/HostnameVerifierTest.java
@@ -0,0 +1,534 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.client;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLException;
+import javax.security.auth.x500.X500Principal;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.client.tls.HostnameVerifier;
+
+public class HostnameVerifierTest {
+
+  private static X509Certificate getCertificate(String certString) throws CertificateException {
+    CertificateFactory cf = CertificateFactory.getInstance("X.509");
+    return (X509Certificate)
+        cf.generateCertificate(new ByteArrayInputStream(certString.getBytes()));
+  }
+
+  private void verifyExceptionEqual(String host, X509Certificate cert, String exceptionMessage) {
+    Exception e =
+        Assertions.assertThrows(SSLException.class, () -> HostnameVerifier.verify(host, cert, -1));
+    Assertions.assertTrue(
+        e.getMessage().contains(exceptionMessage), "real message:" + e.getMessage());
+  }
+
+  // generating certificate example
+  //      openssl genrsa -out "/home/osboxes/key" 2048
+  //      openssl req -new -utf8 -sha1 \
+  //            -key /home/osboxes/key \
+  //            -subj "/C=US/ST=CA/O=Acme, Inc./CN=mariadb.org" \
+  //            -reqexts SAN \
+  //            -config <(cat /etc/ssl/openssl.cnf \
+  //                    <(printf
+  // "\n[SAN]\nsubjectAltName=DNS:mariadbtest.org,DNS:www.mariadbtest.org")) \
+  //            -out domain.csr
+
+  @Test
+  public void verifyCn() throws Exception {
+    // CN=test.com
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIC+zCCAeOgAwIBAgIJANin/585wAXHMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV\n"
+                + "BAMMCHRlc3QuY29tMCAXDTE3MDYyMzEzNTI1NloYDzIxMTcwNTMwMTM1MjU2WjAT\n"
+                + "MREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n"
+                + "ggEBAMQHS31pL/fMkcQBo5zZV2Hi1Jdc1vIIv65d+XeFmv+n/vv+X5Z5NKLc7i01\n"
+                + "SFPoTEr1HG7R6Xvl27UtGm9Z6fmgsCbCRImUCG1yPER20fAgWNhKkoGgvOM8PxZz\n"
+                + "AS0dWgaukBnG9EDVQQrLu+bHuHji8qysGiYQGvSBy/QLSMWjfkSjyFv8I2pT0jLi\n"
+                + "eghgROl3IprRcsiebC/Bv1iJ06s8BD1C9ErzmPxqHaChdzGFATm+G4opcnBxzPuN\n"
+                + "DVE9CaLUS4Q5SixB9TRTQ2LyryEtUOUnnDyoktrX3LzkTmr2dhT8MIgRMsNkJD5w\n"
+                + "CpITvLchBXCdj0lcn5NMb0Rt/AsCAwEAAaNQME4wHQYDVR0OBBYEFJMoFo+HhyIt\n"
+                + "WA6QZmedeN2/qBU/MB8GA1UdIwQYMBaAFJMoFo+HhyItWA6QZmedeN2/qBU/MAwG\n"
+                + "A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGpBkEJ3nv1kCnqQbrU3WYmv\n"
+                + "zl+kNc5xVZdLWMarjvWwBE1cnDHkXzJpl5cyWcHuPyWAi40/edN7gRfpNINWfc0A\n"
+                + "9YWo2PVBlBdklqzsewDV3gipFHkCgBTlGXaPXjCLLNxphYwdsble1hu/XXNvNY8v\n"
+                + "9EPxgN0rTnBj85gme/+Hrjq2kH15jyqK5rdylOjCZELs5g8cc49M6sw/sY70GsGA\n"
+                + "UEjb+vAN7FxXzXzH4oqIeycnxP+/MA82iieew7nlOMlYrppM6igjP0CUzw4ys6lG\n"
+                + "8QdWBcm2Ybo4XFjOnC98VlQl+WBu4CiToxjGphDmsMIO3Hf5PSTRwTKxtuWn45Y=\n"
+                + "-----END CERTIFICATE-----\n");
+    HostnameVerifier.verify("test.com", cert, -1);
+    verifyExceptionEqual(
+        "a.test.com",
+        cert,
+        "DNS host \"a.test.com\" doesn't correspond to certificate CN \"test.com\"");
+    verifyExceptionEqual(
+        "other.com",
+        cert,
+        "DNS host \"other.com\" doesn't correspond to certificate CN \"test.com\"");
+  }
+
+  @Test
+  public void verifyNoSan() throws Exception {
+    // CN=*.mariadb.com
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDLjCCAhYCFEWSUFTlr/qGo/jC5R1nNQdE5zmrMA0GCSqGSIb3DQEBCwUAMFIx\n"
+                + "CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJHRDELMAkGA1UEBwwCU1oxEjAQBgNVBAoM\n"
+                + "CUFjbWUsSW5jLjEVMBMGA1UEAwwMQWNtZSBSb290IENBMCAXDTIxMDMzMDA5MjQ1\n"
+                + "OVoYDzIxMjEwMzA2MDkyNDU5WjBTMQswCQYDVQQGEwJDTjELMAkGA1UECAwCR0Qx\n"
+                + "CzAJBgNVBAcMAlNaMRIwEAYDVQQKDAlBY21lLEluYy4xFjAUBgNVBAMMDSoubWFy\n"
+                + "aWFkYi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdKvfR3PBZ\n"
+                + "7oo4bYlj+Z2F+g2s1Pnurs7KUIu04T8x1KI0tiHniBTuTKL4TinWx734VjnK4pJf\n"
+                + "mwtcWpuxcXY+Btj/C47HMwpZjABI4PbHcB46IVb3gg8XTEDMxZ/OLYACYe+PEwvI\n"
+                + "8Bdmydtn/A6IqIOd2eQTSFCX695CNczSWd3yrirZwe6xZCp2xYemW2UJkrjxRK66\n"
+                + "IpoYWyYVPCe4CiGBL0f6dLrWE6HUPuA3Pb68o0IFGP4NlmXv9qHm8kXejqE216Q/\n"
+                + "Fx4sUS/icH50zs+QtpoKYR8XQnUVeAO8lEuI09mAxII5jtWdYOA/s2oSz5e7m0i2\n"
+                + "xsSHvDJD0P6bAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKE/YucmKZldC2iE330u\n"
+                + "CiP9EvUJfd98j96clpzdqW2V/uDylJP96QDk0iY5rIfoGAu6a9xZP9Bju8F7crLz\n"
+                + "Ogx/Vdq//7uOHMe/kJ3kOjzI8jsdFKGA26BT8wBNZ/UT9ll0iFjYZ1YhsaURslX5\n"
+                + "+uW//GG6vpcMtWIMbkkHZnM5DKeZXF1VX55jrB01kxjaqrObhqNlQl887KQ/j5HF\n"
+                + "iAAiLwDQu171TQmCY7iesYv84cyUqLvRoAfLzOPb62AlLwGNWKeIOFJElnMSDx3y\n"
+                + "LzGv9zUUe1SdqqVASKJAAhzqGyu9eLkGYIKTHU7WdrPSyAhammdeq7C7AYLpMrPc\n"
+                + "CAM=\n"
+                + "-----END CERTIFICATE-----\n");
+    HostnameVerifier.verify("test.mariadb.org", cert, -1);
+    verifyExceptionEqual(
+        "test.org",
+        cert,
+        "DNS host \"test.org\" doesn't correspond to certificate CN \"*.mariadb.org\"");
+  }
+
+  @Test
+  public void verifyNonAsciiCn() throws Exception {
+    // CN=😎.com = "\uD83D\uDE0E"
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDWTCCAkGgAwIBAgIJAI38v686DwcOMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNV\n"
+                + "BAYTAlVTMQswCQYDVQQIDAJDQTETMBEGA1UECgwKQWNtZSwgSW5jLjERMA8GA1UE\n"
+                + "AwwI8J+Yji5jb20wIBcNMTcwNjIzMTQyNzQ2WhgPMjExNzA1MzAxNDI3NDZaMEIx\n"
+                + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTETMBEGA1UECgwKQWNtZSwgSW5jLjER\n"
+                + "MA8GA1UEAwwI8J+Yji5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n"
+                + "AQDEB0t9aS/3zJHEAaOc2Vdh4tSXXNbyCL+uXfl3hZr/p/77/l+WeTSi3O4tNUhT\n"
+                + "6ExK9Rxu0el75du1LRpvWen5oLAmwkSJlAhtcjxEdtHwIFjYSpKBoLzjPD8WcwEt\n"
+                + "HVoGrpAZxvRA1UEKy7vmx7h44vKsrBomEBr0gcv0C0jFo35Eo8hb/CNqU9Iy4noI\n"
+                + "YETpdyKa0XLInmwvwb9YidOrPAQ9QvRK85j8ah2goXcxhQE5vhuKKXJwccz7jQ1R\n"
+                + "PQmi1EuEOUosQfU0U0Ni8q8hLVDlJ5w8qJLa19y85E5q9nYU/DCIETLDZCQ+cAqS\n"
+                + "E7y3IQVwnY9JXJ+TTG9EbfwLAgMBAAGjUDBOMB0GA1UdDgQWBBSTKBaPh4ciLVgO\n"
+                + "kGZnnXjdv6gVPzAfBgNVHSMEGDAWgBSTKBaPh4ciLVgOkGZnnXjdv6gVPzAMBgNV\n"
+                + "HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBknxZ3ihZHmcyrV3H0pNdc+jxB\n"
+                + "xU0T1T1nOLVpgqh+N0m+WFyGdcZlwPcmuD2a5jFn7uIdh8qfq11T8R+OmJqrBxoo\n"
+                + "RSACSAgRSQjPfnN8wi4i8hFLKXOQw43UomsSuNixdGIsMWrDh02e1Q0/g/TD7S62\n"
+                + "JCRksTlBS/+qw+w384vEd4djq7HuT8/hs2RC6Hm9EQkipgNn9+2z40vJ/jgcuPIF\n"
+                + "x51XCozrD1yW9JK/YyBnjYk04iEfQLW7+pGMJOcsX7x9EGwpEg1gsDg2mM0EEIwU\n"
+                + "d6DHlYvpD9JkzyEScg8Supztoc2aGbGE4SHBKB1riTLBAHWqqwas4sGSgZxu\n"
+                + "-----END CERTIFICATE-----\n");
+    HostnameVerifier.verify("😎.com", cert, -1);
+    verifyExceptionEqual(
+        "a.😎.com", cert, "DNS host \"a.😎.com\" doesn't correspond to certificate CN \"😎.com\"");
+  }
+
+  @Test
+  public void verifySubjectAlt() throws Exception {
+    // CN=mariadb.org, subjectAlt=other.org,www.other.org
+    //        openssl genrsa -out ca.key 2048
+    //        openssl req -new -x509 -days 36500 -key ca.key -subj "/C=CN/ST=GD/L=SZ/O=Acme,
+    // Inc./CN=Acme Root CA" -out ca.crt
+    //
+    //        openssl req -newkey rsa:2048 -nodes -keyout server.key -subj "/C=CN/ST=GD/L=SZ/O=Acme,
+    // Inc./CN=*.mariadb.org" \
+    //                  -out server.csr
+    //        openssl x509 -req -extfile <(printf "subjectAltName=DNS:other.org,DNS:www.other.org")
+    // -days 36500 \
+    //                  -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDUzCCAjugAwIBAgIJAPMG38xrY9DcMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV\n"
+                + "BAYTAkNOMQswCQYDVQQIDAJHRDELMAkGA1UEBwwCU1oxEzARBgNVBAoMCkFjbWUs\n"
+                + "IEluYy4xFTATBgNVBAMMDEFjbWUgUm9vdCBDQTAgFw0xNzA2MjMxNjEyNTlaGA8y\n"
+                + "MTE3MDUzMDE2MTI1OVowVDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYD\n"
+                + "VQQHDAJTWjETMBEGA1UECgwKQWNtZSwgSW5jLjEWMBQGA1UEAwwNKi5tYXJpYWRi\n"
+                + "Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZnnLoS2JKQNr/d\n"
+                + "ccRT1pNVKHykAVJHhZiIfjqqKEstjob30VZjll5exQ6iTHaS73qXG1/PfXhEl8Tc\n"
+                + "7R3VlE7dHxPE+FhWSCcdsJlSEpa9h0TOkJ6H4V1iD+bTwlfEesLqXCzLkaBz7hsw\n"
+                + "L6mzVDJ4Lucrstf2YgBEoXjzj8G+ECiz1Vx1GX1jU2yoRYk/LcGUgsbxMxZOFcKG\n"
+                + "JyCmjbRe7xJozhu3m/1bf8eCyHg/+Tpiw1VGwPNFe6mb2SI9pYnk9l0pjzFy5yxJ\n"
+                + "nFeYj5cLBZHwM5K2aHiOvvBeXvYz9RIrWI98zsXZFjzD00+Js3X/jC4nRtkHV/JC\n"
+                + "COvAwRUCAwEAAaMnMCUwIwYDVR0RBBwwGoIJb3RoZXIub3Jngg13d3cub3RoZXIu\n"
+                + "b3JnMA0GCSqGSIb3DQEBCwUAA4IBAQDEswEEw2VXv6+EKIz3ysN7kRNXs09TWiYd\n"
+                + "bhGIVWHK4oRMjbUkPQWNftD+VvRyW1mZPZ0Tn/kXPnUsYCuF/UFLautmIAa16/el\n"
+                + "WJc9EA4yM42CByW/DEUfvFVgaBoJysLNhA2O/1VC/UmC2TNjiwXAO3AOJTVgdS1/\n"
+                + "nj34C3SJgbtmMu/ToCILMcjkaKJPD2/1AaIioBOSxvwdseM399eVjZIhf9bQCSHU\n"
+                + "fDrV4El/nb5nr4j7AvHtIhbPtpJOmKCAbZRwKc+ZgrH6ZyapyZfpmNmlwZcuC4DM\n"
+                + "SJmVrJfl1GdaXyxsljClcXM9MDQYm9r9wcchc3dSVR+k6wz2+vbw\n"
+                + "-----END CERTIFICATE-----\n");
+
+    verifyExceptionEqual(
+        "mariadb.org",
+        cert,
+        "DNS host \"mariadb.org\" doesn't correspond to certificate "
+            + "CN \"*.mariadb.org\" and SAN[{DNS:\"other.org\"},{DNS:\"www.other.org\"}]");
+    HostnameVerifier.verify("a.mariadb.org", cert, -1);
+    verifyExceptionEqual(
+        "a.other2.org",
+        cert,
+        "DNS host \"a.other2.org\" doesn't correspond to certificate "
+            + "CN \"*.mariadb.org\" and SAN[{DNS:\"other.org\"},{DNS:\"www.other.org\"}]");
+    HostnameVerifier.verify("other.org", cert, -1);
+    verifyExceptionEqual(
+        "a.other.org",
+        cert,
+        "DNS host \"a.other.org\" doesn't correspond to certificate "
+            + "CN \"*.mariadb.org\" and SAN[{DNS:\"other.org\"},{DNS:\"www.other.org\"}]");
+    HostnameVerifier.verify("www.other.org", cert, -1);
+  }
+
+  @Test
+  public void verifySubjectAltOnly() throws Exception {
+    // subjectAlt=foo.com
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIESjCCAzKgAwIBAgIJAIz+EYMBU6aYMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n"
+                + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n"
+                + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n"
+                + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n"
+                + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MjYxMFoXDTI4MTEwNTE2MjYxMFowgZIx\n"
+                + "CzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNYXJ5bGFuZDEUMBIGA1UEBwwLRm9yZXN0\n"
+                + "IEhpbGwxFzAVBgNVBAoMDmh0dHBjb21wb25lbnRzMRowGAYDVQQLDBF0ZXN0IGNl\n"
+                + "cnRpZmljYXRlczElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNv\n"
+                + "bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMhjr5aCPoyp0R1iroWA\n"
+                + "fnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2BlYho4O84X244QrZTRl8kQbYt\n"
+                + "xnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRyzerA/ZtrlUqf+lKo0uWcocxe\n"
+                + "Rc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY07hNKXAb2odnVqgzcYiDkLV8\n"
+                + "ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8BqnGd87xQU3FVZI4tbtkB+Kz\n"
+                + "jD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiVJTxpTKqym93whYk93l3ocEe5\n"
+                + "5c0CAwEAAaOBkDCBjTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM\n"
+                + "IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUnxR3vz86tso4gkJIFiza\n"
+                + "0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLSrNuzA1LKh6YNPg0wEgYDVR0RBAsw\n"
+                + "CYIHZm9vLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAjl78oMjzFdsMy6F1sGg/IkO8\n"
+                + "tF5yUgPgFYrs41yzAca7IQu6G9qtFDJz/7ehh/9HoG+oqCCIHPuIOmS7Sd0wnkyJ\n"
+                + "Y7Y04jVXIb3a6f6AgBkEFP1nOT0z6kjT7vkA5LJ2y3MiDcXuRNMSta5PYVnrX8aZ\n"
+                + "yiqVUNi40peuZ2R8mAUSBvWgD7z2qWhF8YgDb7wWaFjg53I36vWKn90ZEti3wNCw\n"
+                + "qAVqixM+J0qJmQStgAc53i2aTMvAQu3A3snvH/PHTBo+5UL72n9S1kZyNCsVf1Qo\n"
+                + "n8jKTiRriEM+fMFlcgQP284EBFzYHyCXFb9O/hMjK2+6mY9euMB1U1aFFzM/Bg==\n"
+                + "-----END CERTIFICATE-----\n");
+    HostnameVerifier.verify("foo.com", cert, -1);
+    verifyExceptionEqual(
+        "a.foo.com",
+        cert,
+        "CN not found in certificate principal \"EMAILADDRESS=juliusdavies@gmail.com, OU=test"
+            + " certificates, O=httpcomponents, L=Forest Hill, ST=Maryland, C=US\" and DNS host"
+            + " \"a.foo.com\" doesn't correspond to SAN[{DNS:\"foo.com\"}]");
+  }
+
+  @Test
+  public void noCn() throws Exception {
+    // subjectAlt=foo.com
+    X509Certificate cert =
+        getCertificate(
+            "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDazCCAlOgAwIBAgIUFxeXaoK5VSZBV1UdBhcDIB0abUAwDQYJKoZIhvcNAQEF\n"
+                + "BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\n"
+                + "GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTA0MTQxNjIxMTlaFw0zMTA0\n"
+                + "MTIxNjIxMTlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw\n"
+                + "HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB\n"
+                + "AQUAA4IBDwAwggEKAoIBAQDRmmo+05f5oqKFidWhk6+EbCNJzxJ7fwrGV13ZfqqP\n"
+                + "HSyxZIcWI/bK6BCjb9BxJa/QaaThr6x7GxI6PaDqRWInpuHepqIBL2arJLq2H3ys\n"
+                + "2zErfA5n0rFkryYW6zQUW/TJTxz5dbagemYA4TvS5Tshm0fimtNDTcv6Vb7U3OXc\n"
+                + "pa42VeLgaaM+OeCQlFH4OEXzGqXwqU090D2aRp05uPJRCFhwvMI9QXG2R8zXogTx\n"
+                + "TAlmxm4piKmg123TLd2N1TxJHxskg4OR5guO/XaG/Zji4KCKJ7dJFHjvNztG0Nme\n"
+                + "dxOo/+I/AeWhLEq81fzGMg4/BYeU1cLv6wnqFi4pbyWLAgMBAAGjUzBRMB0GA1Ud\n"
+                + "DgQWBBTLvLm0GjjbZOg5fJYgt80FvCgxNzAfBgNVHSMEGDAWgBTLvLm0GjjbZOg5\n"
+                + "fJYgt80FvCgxNzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBp\n"
+                + "3Z8UMM8y++04mKRZEP7y88dmmLOt64TRjJhTFoHvZsC/VZi5glt3/FnYxhlf8sfQ\n"
+                + "sJB+TRlVcEWBff6yJd/uUScff56Zgy2PCCL4rjgBjxgq/kf28m6tC8nHlx88qz0Y\n"
+                + "CZR9eEwTN8xgRvgUx5OFNewDYpkY0QAHkzAddCl5uaO6Mi0E34gSECIQ/cJ75xhQ\n"
+                + "K3Qy/qj1Kl7r80WJtzmhpZbpKbVZXa3NpwTWUfaD6WhNW0H/BhAnQq3XkXVWK6sW\n"
+                + "rLfHdWz9hQ79AiNaTc1I3YDyrnNEQBvHAFZ87Y8XIk4RaPzttLAfL/IKHuJdb85M\n"
+                + "cMq0UjgrIuCJoKB8kcm/\n"
+                + "-----END CERTIFICATE-----");
+    verifyExceptionEqual(
+        "a.foo.com",
+        cert,
+        "CN not found in certificate principal \"O=Internet Widgits Pty Ltd, ST=Some-State, C=AU\""
+            + " and certificate doesn't contain SAN");
+  }
+
+  @Test
+  public void verifyMultipleCn() throws Exception {
+    // CN=test1.org, CN=test2.org
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDgzCCAmugAwIBAgIJAPqfD+J8D4gqMA0GCSqGSIb3DQEBBQUAMFcxCzAJBgNV\n"
+                + "BAYTAlVTMQswCQYDVQQIDAJDQTETMBEGA1UECgwKQWNtZSwgSW5jLjESMBAGA1UE\n"
+                + "AwwJdGVzdDEub3JnMRIwEAYDVQQDDAl0ZXN0Mi5vcmcwIBcNMTcwNjIzMTYxNDIx\n"
+                + "WhgPMjExNzA1MzAxNjE0MjFaMFcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTET\n"
+                + "MBEGA1UECgwKQWNtZSwgSW5jLjESMBAGA1UEAwwJdGVzdDEub3JnMRIwEAYDVQQD\n"
+                + "DAl0ZXN0Mi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEB0t9\n"
+                + "aS/3zJHEAaOc2Vdh4tSXXNbyCL+uXfl3hZr/p/77/l+WeTSi3O4tNUhT6ExK9Rxu\n"
+                + "0el75du1LRpvWen5oLAmwkSJlAhtcjxEdtHwIFjYSpKBoLzjPD8WcwEtHVoGrpAZ\n"
+                + "xvRA1UEKy7vmx7h44vKsrBomEBr0gcv0C0jFo35Eo8hb/CNqU9Iy4noIYETpdyKa\n"
+                + "0XLInmwvwb9YidOrPAQ9QvRK85j8ah2goXcxhQE5vhuKKXJwccz7jQ1RPQmi1EuE\n"
+                + "OUosQfU0U0Ni8q8hLVDlJ5w8qJLa19y85E5q9nYU/DCIETLDZCQ+cAqSE7y3IQVw\n"
+                + "nY9JXJ+TTG9EbfwLAgMBAAGjUDBOMB0GA1UdDgQWBBSTKBaPh4ciLVgOkGZnnXjd\n"
+                + "v6gVPzAfBgNVHSMEGDAWgBSTKBaPh4ciLVgOkGZnnXjdv6gVPzAMBgNVHRMEBTAD\n"
+                + "AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQANlc974MeEIjEG8PzjDuiCbImZU/vxmBu1\n"
+                + "QD4mOfTjoixx/o9w/TbtnYhlugH3Nb2biaIx+2VnQAjk6euNBdFXW1cIawstrYGn\n"
+                + "KKEbZgQ7rgWfqyXIUK5NgX5jqxv5iW2xQE9nFGum8ouy8t+Nwi5F5uPGlhw/POnZ\n"
+                + "SLdP5i67GJN/Ho2HCfYOWm8STo0S7jmxtGoLcZ/EPaM3DaqLQYTdjtNKuotw1YuF\n"
+                + "A94gKVaU6XS6EdDGc6oSfKAR/pqKnWAmDc0ofvYniojquzm4fUO3JgzXN/xTDPUc\n"
+                + "GiY3dV92GD9wZfbUWsQRzLizRzIrsvZfCn/LLeUvOQPuCCeLzIxD\n"
+                + "-----END CERTIFICATE-----\n");
+    HostnameVerifier.verify("test1.org", cert, -1);
+    verifyExceptionEqual(
+        "test2.org",
+        cert,
+        "DNS host \"test2.org\" doesn't correspond to certificate CN \"test1.org\"");
+  }
+
+  @Test
+  public void verifyWilcardCn() throws Exception {
+    // CN=*.foo.com
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIESDCCAzCgAwIBAgIJAIz+EYMBU6aUMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n"
+                + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n"
+                + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n"
+                + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n"
+                + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MTU1NVoXDTI4MTEwNTE2MTU1NVowgaYx\n"
+                + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n"
+                + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n"
+                + "cnRpZmljYXRlczESMBAGA1UEAxQJKi5mb28uY29tMSUwIwYJKoZIhvcNAQkBFhZq\n"
+                + "dWxpdXNkYXZpZXNAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n"
+                + "CgKCAQEAyGOvloI+jKnRHWKuhYB+cTIEwZhagKJ0f3rIY8WNgujB7PlpgpjUg4pN\n"
+                + "jYGViGjg7zhfbjhCtlNGXyRBti3GcaHiBIIP5nyCNn+Ay8tSWGo5v5Zc8BQcwHf0\n"
+                + "ZHLN6sD9m2uVSp/6UqjS5ZyhzF5FzvvUo3xw8fecdnStXQfHhkBnLpTjHE5t7iu1\n"
+                + "JVjTuE0pcBvah2dWqDNxiIOQtXyKW8Sag1YxaunxQGqRNykSFiEJindxOSAnAxK6\n"
+                + "q/wGqcZ3zvFBTcVVkji1u2QH4rOMP3PPxAIMkB8ONkdHTco1DmbE6BfDHArDqUYx\n"
+                + "qJUlPGlMqrKb3fCFiT3eXehwR7nlzQIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCG\n"
+                + "SAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4E\n"
+                + "FgQUnxR3vz86tso4gkJIFiza0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLSrNuz\n"
+                + "A1LKh6YNPg0wDQYJKoZIhvcNAQEFBQADggEBAH0ipG6J561UKUfgkeW7GvYwW98B\n"
+                + "N1ZooWX+JEEZK7+Pf/96d3Ij0rw9ACfN4bpfnCq0VUNZVSYB+GthQ2zYuz7tf/UY\n"
+                + "A6nxVgR/IjG69BmsBl92uFO7JTNtHztuiPqBn59pt+vNx4yPvno7zmxsfI7jv0ww\n"
+                + "yfs+0FNm7FwdsC1k47GBSOaGw38kuIVWqXSAbL4EX9GkryGGOKGNh0qvAENCdRSB\n"
+                + "G9Z6tyMbmfRY+dLSh3a9JwoEcBUso6EWYBakLbq4nG/nvYdYvG9ehrnLVwZFL82e\n"
+                + "l3Q/RK95bnA6cuRClGusLad0e6bjkBzx/VQ3VarDEpAkTLUGVAa0CLXtnyc=\n"
+                + "-----END CERTIFICATE-----\n");
+    verifyExceptionEqual(
+        "foo.com", cert, "DNS host \"foo.com\" doesn't correspond to certificate CN \"*.foo.com\"");
+    HostnameVerifier.verify("www.foo.com", cert, -1);
+    HostnameVerifier.verify("花子.foo.com", cert, -1);
+    verifyExceptionEqual(
+        "a.b.foo.com",
+        cert,
+        "DNS host \"a.b.foo.com\" doesn't correspond to certificate CN \"*.foo.com\"");
+  }
+
+  @Test
+  public void verifyWilcardCnOnTld() throws Exception {
+    // It's the CA's responsibility to not issue broad-matching certificates!
+    // CN=*.co.jp
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIERjCCAy6gAwIBAgIJAIz+EYMBU6aVMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n"
+                + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n"
+                + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n"
+                + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n"
+                + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MTYzMFoXDTI4MTEwNTE2MTYzMFowgaQx\n"
+                + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n"
+                + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n"
+                + "cnRpZmljYXRlczEQMA4GA1UEAxQHKi5jby5qcDElMCMGCSqGSIb3DQEJARYWanVs\n"
+                + "aXVzZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n"
+                + "ggEBAMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2B\n"
+                + "lYho4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRy\n"
+                + "zerA/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY\n"
+                + "07hNKXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8\n"
+                + "BqnGd87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiV\n"
+                + "JTxpTKqym93whYk93l3ocEe55c0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgB\n"
+                + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE\n"
+                + "FJ8Ud78/OrbKOIJCSBYs2tDLXofYMB8GA1UdIwQYMBaAFHua2o+QmU5S0qzbswNS\n"
+                + "yoemDT4NMA0GCSqGSIb3DQEBBQUAA4IBAQA0sWglVlMx2zNGvUqFC73XtREwii53\n"
+                + "CfMM6mtf2+f3k/d8KXhLNySrg8RRlN11zgmpPaLtbdTLrmG4UdAHHYr8O4y2BBmE\n"
+                + "1cxNfGxxechgF8HX10QV4dkyzp6Z1cfwvCeMrT5G/V1pejago0ayXx+GPLbWlNeZ\n"
+                + "S+Kl0m3p+QplXujtwG5fYcIpaGpiYraBLx3Tadih39QN65CnAh/zRDhLCUzKyt9l\n"
+                + "UGPLEUDzRHMPHLnSqT1n5UU5UDRytbjJPXzF+l/+WZIsanefWLsxnkgAuZe/oMMF\n"
+                + "EJMryEzOjg4Tfuc5qM0EXoPcQ/JlheaxZ40p2IyHqbsWV4MRYuFH4bkM\n"
+                + "-----END CERTIFICATE-----\n");
+    HostnameVerifier.verify("foo.co.jp", cert, -1);
+    HostnameVerifier.verify("花子.co.jp", cert, -1);
+  }
+
+  @Test
+  public void subjectAltUsesLocalDomainAndIp() throws Exception {
+    // /C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=*.mariadb.org,
+    // subjectAltName=DNS:localhost.localdomain,DNS:localhost,IP:127.0.0.1
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDfDCCAmSgAwIBAgIURZJQVOWv+oaj+MLlHWc1B0TnOaowDQYJKoZIhvcNAQEL\n"
+                + "BQAwUjELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYDVQQHDAJTWjESMBAG\n"
+                + "A1UECgwJQWNtZSxJbmMuMRUwEwYDVQQDDAxBY21lIFJvb3QgQ0EwIBcNMjEwMzMw\n"
+                + "MDkwODAxWhgPMjEyMTAzMDYwOTA4MDFaMFMxCzAJBgNVBAYTAkNOMQswCQYDVQQI\n"
+                + "DAJHRDELMAkGA1UEBwwCU1oxEjAQBgNVBAoMCUFjbWUsSW5jLjEWMBQGA1UEAwwN\n"
+                + "Ki5tYXJpYWRiLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAJ\n"
+                + "xqbqTGmwO5n3kVd6QJPRSh+0M1HIQacyM/tkE7jLw3725/KtknuwuFbPpxKyTCLC\n"
+                + "IoNx4yaBbmx783OPP3pokXTWiMdrVZdLltBNamNzekNFN4YhR5oN479M5cKgrk94\n"
+                + "Ud+ql0NN5FscrSQ0fSdJf0idJMqThro1MJVp9rp5cdCba6/lKyDbdOybe5f7rmrg\n"
+                + "+37J+src67+rqwVT8ZwZgLTGDf4X9OSIzyw6+PCWYWr89aurrOuOyqA3QqXVRZa/\n"
+                + "IxOMHIdzXMgLN6+HduwdZ+DNv1NPT2MDlRQvOnDop3NoEVKWekOTv50LbKRgWTYO\n"
+                + "TK/dfcsDpZmdyHv7pb8CAwEAAaNHMEUwQwYDVR0RBDwwOoIVbG9jYWxob3N0Lmxv\n"
+                + "Y2FsZG9tYWlugglsb2NhbGhvc3SHBH8AAAGHECABDbg5AjRoAAAAAAAABEMwDQYJ\n"
+                + "KoZIhvcNAQELBQADggEBAHsiJz9cpmL8BTa/o10S+pmap3iOnYYuJT0llCRLJ+Ji\n"
+                + "msO2niyIwqCJHMLcEABCENJt0HDOEKlnunVgc+X/6K8DnPrYhfWQbYI/dwUBoSIQ\n"
+                + "siK/yKW0q+S+YjCVpNMA3iMfhJ9Qe9LDO+xdCBhzplgrV8YwG+J2FUNbZfvl5cML\n"
+                + "TjKLWrWo9dgZyH/7mjwryRzswfUfr/lRARCyrMotaXfYmjPjwTSRc0aPGrEjs3ns\n"
+                + "WMtimgh7Zw3Tbxc51miz9CRy767lq/9BGTdeBLmW0EXssIJb9uO0Ht3C/Pqy0ojk\n"
+                + "8e1eYtofjTsqWHZ1s2LhtT0HvXdL6BnWP9GWc/zxiKM=\n"
+                + "-----END CERTIFICATE-----\n");
+    assertEquals(
+        new X500Principal("CN=*.mariadb.org, O=\"Acme,Inc.\", L=SZ, ST=GD, C=CN"),
+        cert.getSubjectX500Principal());
+
+    HostnameVerifier.verify("localhost", cert, -1);
+    HostnameVerifier.verify("localhost.localdomain", cert, -1);
+    verifyExceptionEqual(
+        "local.host",
+        cert,
+        "DNS host \"local.host\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
+
+    HostnameVerifier.verify("127.0.0.1", cert, -1);
+    verifyExceptionEqual(
+        "127.0.0.2",
+        cert,
+        "IPv4 host \"127.0.0.2\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
+
+    HostnameVerifier.verify("2001:db8:3902:3468:0:0:0:443", cert, -1);
+    verifyExceptionEqual(
+        "2001:db8:1::",
+        cert,
+        "IPv6 host \"2001:db8:1::\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
+  }
+
+  @Test
+  public void wildcardsCannotMatchIpAddresses() throws Exception {
+    // openssl req -x509 -nodes -days 36500 -subj '/CN=*.0.0.1' -newkey rsa:512 -out cert.pem
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDVzCCAj+gAwIBAgIJAN9L/Y9e1F7dMA0GCSqGSIb3DQEBBQUAMEExCzAJBgNV\n"
+                + "BAYTAlVTMQswCQYDVQQIDAJDQTETMBEGA1UECgwKQWNtZSwgSW5jLjEQMA4GA1UE\n"
+                + "AwwHKi4wLjAuMTAgFw0xNzA2MjMxNTU3MTdaGA8yMTE3MDUzMDE1NTcxN1owQTEL\n"
+                + "MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQKDApBY21lLCBJbmMuMRAw\n"
+                + "DgYDVQQDDAcqLjAuMC4xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n"
+                + "xAdLfWkv98yRxAGjnNlXYeLUl1zW8gi/rl35d4Wa/6f++/5flnk0otzuLTVIU+hM\n"
+                + "SvUcbtHpe+XbtS0ab1np+aCwJsJEiZQIbXI8RHbR8CBY2EqSgaC84zw/FnMBLR1a\n"
+                + "Bq6QGcb0QNVBCsu75se4eOLyrKwaJhAa9IHL9AtIxaN+RKPIW/wjalPSMuJ6CGBE\n"
+                + "6XcimtFyyJ5sL8G/WInTqzwEPUL0SvOY/GodoKF3MYUBOb4biilycHHM+40NUT0J\n"
+                + "otRLhDlKLEH1NFNDYvKvIS1Q5SecPKiS2tfcvOROavZ2FPwwiBEyw2QkPnAKkhO8\n"
+                + "tyEFcJ2PSVyfk0xvRG38CwIDAQABo1AwTjAdBgNVHQ4EFgQUkygWj4eHIi1YDpBm\n"
+                + "Z5143b+oFT8wHwYDVR0jBBgwFoAUkygWj4eHIi1YDpBmZ5143b+oFT8wDAYDVR0T\n"
+                + "BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAAE4YYuS94g9EyIRvPeXcHlJsjG1n\n"
+                + "moSZIVgSuKjLAb31SOyY+2c534SUELED7ECEb4yKM7WmWctpF0anFZUDCczuo+zl\n"
+                + "uuTv1k/TE9GBWizxZgu/vX7+FAbxAgkA9Jxn2phJlks+PwnUClzVBzJ77zPNzIO8\n"
+                + "6s8waZr9ttnASBHVaeSKkknI+gas5KpvY+B4eRxZx0G8Fyher29yIiE44Z6RHzjI\n"
+                + "+EnURTvdjd2ZuY5QKvwlBQssqOHxDATg8pL6JmgnrvbYqh+FBpUN8sqwrXx6q8dz\n"
+                + "aUH7ncQGgwZBAUIiQaKlb0QYpcyrMlGWNri+RFt+Goz5S3BxxobwfiaBoA==\n"
+                + "-----END CERTIFICATE-----\n");
+    verifyExceptionEqual(
+        "127.0.0.1",
+        cert,
+        "IPv4 host \"127.0.0.1\" doesn't correspond to "
+            + "certificate CN \"*.0.0.1\" : wildcards not possible for IPs");
+  }
+
+  @Test
+  public void subjectAltNameWithWildcard() throws Exception {
+    // subjectAltName=DNS:*.other.org,DNS:a*b.other2.com
+    X509Certificate cert =
+        getCertificate(
+            ""
+                + "-----BEGIN CERTIFICATE-----\n"
+                + "MIIDVjCCAj6gAwIBAgIJAPMG38xrY9DaMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV\n"
+                + "BAYTAkNOMQswCQYDVQQIDAJHRDELMAkGA1UEBwwCU1oxEzARBgNVBAoMCkFjbWUs\n"
+                + "IEluYy4xFTATBgNVBAMMDEFjbWUgUm9vdCBDQTAgFw0xNzA2MjMxNjA1MTlaGA8y\n"
+                + "MTE3MDUzMDE2MDUxOVowVDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYD\n"
+                + "VQQHDAJTWjETMBEGA1UECgwKQWNtZSwgSW5jLjEWMBQGA1UEAwwNKi5tYXJpYWRi\n"
+                + "Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKqUYr7IHOuE1FD3\n"
+                + "4AX/23DZ/VnK3U/sZNLfdP9322pO5HP4yv3HzHNtkl+3s/jKnRBwOpGjvmeoVgro\n"
+                + "B8NK7Prs8tCMET9yfFXg/gSkoMAnR4g1jExB9bszTRN1+5dmLZK7xoKcRYtdKCLB\n"
+                + "AeGYAx6lSKFkc5sAuU8e9k9iAdD+j2w4s5UbP2QTK6N97+EMGTYjQ91ynsxzUltX\n"
+                + "5ueRLbg0M5WyRZpB4oH3J5T2L+NzpjU60Lhny/Kz5fCDizkwYjYBV+p9bhneklia\n"
+                + "ByBxGm/y+yrDm5RDRICws5UhjWEe5ztOrfLwjZGmkYgcr2iuVqR3yhXoQIrxK1OV\n"
+                + "8RnNJSECAwEAAaMqMCgwJgYDVR0RBB8wHYILKi5vdGhlci5vcmeCDmEqYi5vdGhl\n"
+                + "cjIuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAAgqjYSzvgc+lUa/8gEpX9QJVvvDN9\n"
+                + "nKqsJIB8G7uSGQgjq1eA8LrklTo1X3uER2+dLfoHIvJJxzuqRF6ugDnHMW+ocITY\n"
+                + "yYkvb1Ok/aKo9e9sEKhndT47A9fjGoN94xhEEfVL8oc2g5gnNQ/+YHwO0vajdh2V\n"
+                + "CMpkFvvSClvomb91u/leWwu1C07dJWHM2OzldEmlQK9sm847YofEfXe5FZXt+Py2\n"
+                + "zpmwb3/djqBpSwdMgBB3us2wEiHN95EGRCT8BmTZ4gFtfdXt6uAZOd93NAoYlmpV\n"
+                + "Flo8jrfEOHRCrdYqXobC/YVuxk+1h+Q2Nu5mKzbc3XfpG1LGGZB98+FP\n"
+                + "-----END CERTIFICATE-----\n");
+
+    verifyExceptionEqual(
+        "other.org",
+        cert,
+        "DNS host \"other.org\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"*.other.org\"},{DNS:\"a*b.other2.com\"}]");
+    HostnameVerifier.verify("www.other.org", cert, -1);
+    verifyExceptionEqual(
+        "other2.org",
+        cert,
+        "DNS host \"other2.org\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"*.other.org\"},{DNS:\"a*b.other2.com\"}]");
+    verifyExceptionEqual(
+        "www.other2.org",
+        cert,
+        "DNS host \"www.other2.org\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"*.other.org\"},{DNS:\"a*b.other2.com\"}]");
+    HostnameVerifier.verify("ab.other2.com", cert, -1);
+    HostnameVerifier.verify("axxxxb.other2.com", cert, -1);
+    verifyExceptionEqual(
+        "axxxxbc.other2.org",
+        cert,
+        "DNS host \"axxxxbc.other2.org\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"*.other.org\"},{DNS:\"a*b.other2.com\"}]");
+    verifyExceptionEqual(
+        "caxxxxb.other2.org",
+        cert,
+        "DNS host \"caxxxxb.other2.org\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+            + " SAN[{DNS:\"*.other.org\"},{DNS:\"a*b.other2.com\"}]");
+    verifyExceptionEqual(
+        "a.axxxxb.other2.org",
+        cert,
+        "DNS host \"a.axxxxb.other2.org\" doesn't correspond to certificate CN \"*.mariadb.org\""
+            + " and SAN[{DNS:\"*.other.org\"},{DNS:\"a*b.other2.com\"}]");
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/client/PrepareCacheTest.java b/src/test/java/org/mariadb/jdbc/unit/client/PrepareCacheTest.java
new file mode 100644
index 0000000..4f06e34
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/client/PrepareCacheTest.java
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.client;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.client.impl.PrepareCache;
+import org.mariadb.jdbc.message.server.PrepareResultPacket;
+
+public class PrepareCacheTest {
+
+  @Test
+  public void check() {
+    PrepareCache cache = new PrepareCache(20, null);
+    try {
+      cache.get("dd");
+      fail();
+    } catch (IllegalStateException s) {
+      assertTrue(s.getMessage().contains("not available method"));
+    }
+    try {
+      cache.put("dd", (PrepareResultPacket) null);
+      fail();
+    } catch (IllegalStateException s) {
+      assertTrue(s.getMessage().contains("not available method"));
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/client/ServerVersionUtilityTest.java b/src/test/java/org/mariadb/jdbc/unit/client/ServerVersionUtilityTest.java
new file mode 100644
index 0000000..2107533
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/client/ServerVersionUtilityTest.java
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.client;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.message.server.util.ServerVersionUtility;
+
+public class ServerVersionUtilityTest {
+
+  @Test
+  public void check() {
+    ServerVersionUtility ver = new ServerVersionUtility("10.5.2", true);
+    assertEquals(10, ver.getMajorVersion());
+    assertEquals(5, ver.getMinorVersion());
+    assertEquals(2, ver.getPatchVersion());
+    assertEquals("10.5.2", ver.getVersion());
+    assertTrue(ver.isMariaDBServer());
+    assertTrue(ver.versionGreaterOrEqual(10, 5, 1));
+    assertTrue(ver.versionGreaterOrEqual(10, 4, 5));
+    assertTrue(ver.versionGreaterOrEqual(5, 6, 5));
+    assertTrue(ver.versionGreaterOrEqual(10, 5, 2));
+    assertFalse(ver.versionGreaterOrEqual(10, 5, 3));
+    assertFalse(ver.versionGreaterOrEqual(10, 6, 0));
+    assertFalse(ver.versionGreaterOrEqual(11, 0, 0));
+
+    ver = new ServerVersionUtility("10.5.2-MariaDB", true);
+    assertEquals(10, ver.getMajorVersion());
+    assertEquals(5, ver.getMinorVersion());
+    assertEquals(2, ver.getPatchVersion());
+    assertEquals("10.5.2-MariaDB", ver.getVersion());
+    assertTrue(ver.isMariaDBServer());
+    assertTrue(ver.versionGreaterOrEqual(10, 5, 1));
+    assertTrue(ver.versionGreaterOrEqual(10, 4, 5));
+    assertTrue(ver.versionGreaterOrEqual(5, 6, 5));
+    assertTrue(ver.versionGreaterOrEqual(10, 5, 2));
+    assertFalse(ver.versionGreaterOrEqual(10, 5, 3));
+    assertFalse(ver.versionGreaterOrEqual(10, 6, 0));
+    assertFalse(ver.versionGreaterOrEqual(11, 0, 0));
+
+    ver = new ServerVersionUtility("8.0.12-something", false);
+    assertEquals(8, ver.getMajorVersion());
+    assertEquals(0, ver.getMinorVersion());
+    assertEquals(12, ver.getPatchVersion());
+    assertEquals("8.0.12-something", ver.getVersion());
+    assertFalse(ver.isMariaDBServer());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/client/result/CompleteResultTest.java b/src/test/java/org/mariadb/jdbc/unit/client/result/CompleteResultTest.java
new file mode 100644
index 0000000..a9e6159
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/client/result/CompleteResultTest.java
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.client.result;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.result.CompleteResult;
+import org.mariadb.jdbc.integration.Common;
+
+public class CompleteResultTest extends Common {
+
+  /** SELECT query cannot be rewritable. */
+  @Test
+  public void metaQuery() throws SQLException {
+    // SELECT query cannot be rewritable
+    String[] columnNames =
+        new String[] {
+          "small",
+          "big123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
+        };
+    DataType[] columnTypes = new DataType[] {DataType.STRING, DataType.STRING};
+    String[][] data =
+        new String[][] {
+          new String[] {
+            "small",
+            "big123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
+          }
+        };
+    ResultSet rs =
+        CompleteResult.createResultSet(columnNames, columnTypes, data, sharedConn.getContext(), 0);
+    assertTrue(rs.next());
+    assertEquals(data[0][0], rs.getString(1));
+    assertEquals(data[0][1], rs.getString(2));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/client/socket/PacketWriterTest.java b/src/test/java/org/mariadb/jdbc/unit/client/socket/PacketWriterTest.java
new file mode 100644
index 0000000..0b86e16
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/client/socket/PacketWriterTest.java
@@ -0,0 +1,25 @@
+package org.mariadb.jdbc.unit.client.socket;
+
+import java.io.IOException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.client.socket.impl.PacketWriter;
+
+public class PacketWriterTest {
+
+  @Test
+  public void growBuffer() throws IOException {
+    PacketWriter pw = new PacketWriter(null, 0, 0xffffff, null, null);
+    Assertions.assertEquals(4, pw.pos());
+    pw.writeBytes(new byte[8190], 0, 8190);
+    pw.writeAscii("abcdefghij");
+    Assertions.assertEquals(8200, pw.pos() - 4);
+
+    for (int i = 0; i < 8190; i++) {
+      Assertions.assertEquals(0, pw.buf()[i + 4]);
+    }
+    for (int i = 0; i < 10; i++) {
+      Assertions.assertEquals('a' + i, pw.buf()[i + 8194]);
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/client/tls/MariaDbX509KeyManagerTest.java b/src/test/java/org/mariadb/jdbc/unit/client/tls/MariaDbX509KeyManagerTest.java
new file mode 100644
index 0000000..b471f2a
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/client/tls/MariaDbX509KeyManagerTest.java
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.client.tls;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.*;
+import java.security.cert.CertificateException;
+import javax.security.auth.x500.X500Principal;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.client.tls.MariaDbX509KeyManager;
+
+public class MariaDbX509KeyManagerTest {
+
+  @Test
+  public void check() throws Exception {
+    MariaDbX509KeyManager keyMger = get();
+    String[] aliases = keyMger.getClientAliases("RSA", null);
+    assertEquals(1, aliases.length);
+    assertEquals("mysqlalias", aliases[0]);
+
+    assertNull(
+        keyMger.getClientAliases(
+            "RSA", new Principal[] {new X500Principal("CN=Android Debug,O=Android,C=US")}));
+    aliases =
+        keyMger.getClientAliases(
+            "RSA",
+            new Principal[] {
+              new X500Principal("EMAILADDRESS=X, OU=X, CN=ca.example.com, L=X, O=X, ST=X, C=XX")
+            });
+    assertEquals(1, aliases.length);
+    assertEquals("mysqlalias", aliases[0]);
+
+    assertNull(keyMger.getPrivateKey("wrong"));
+    assertNotNull(keyMger.getPrivateKey("mysqlalias"));
+
+    assertNull(keyMger.getCertificateChain("wrong"));
+    assertNotNull(keyMger.getCertificateChain("mysqlalias"));
+
+    assertEquals(
+        "mysqlalias",
+        keyMger.chooseEngineClientAlias(
+            new String[] {"RSA"},
+            new Principal[] {
+              new X500Principal("EMAILADDRESS=X, OU=X, CN=ca.example.com, L=X, O=X, ST=X, C=XX")
+            },
+            null));
+    assertNull(
+        keyMger.chooseEngineClientAlias(
+            new String[] {},
+            new Principal[] {
+              new X500Principal("EMAILADDRESS=X, OU=X, CN=ca.example.com, L=X, O=X, ST=X, C=XX")
+            },
+            null));
+    assertNull(
+        keyMger.chooseEngineClientAlias(
+            null,
+            new Principal[] {
+              new X500Principal("EMAILADDRESS=X, OU=X, CN=ca.example.com, L=X, O=X, ST=X, C=XX")
+            },
+            null));
+    assertNull(keyMger.getServerAliases("RSA", null));
+    assertNull(keyMger.chooseServerAlias("RSA", null, null));
+    assertNull(keyMger.chooseEngineServerAlias("RSA", null, null));
+  }
+
+  private MariaDbX509KeyManager get()
+      throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
+    try (InputStream inStream =
+        MariaDbX509KeyManagerTest.class
+            .getClassLoader()
+            .getResourceAsStream("testclient-keystore.p12")) {
+      assertNotNull(inStream);
+      char[] keyStorePasswordChars = "kspass".toCharArray();
+      KeyStore ks = KeyStore.getInstance("PKCS12");
+      ks.load(inStream, keyStorePasswordChars);
+      return new MariaDbX509KeyManager(ks, keyStorePasswordChars);
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/client/tls/MariaDbX509TrustingManagerTest.java b/src/test/java/org/mariadb/jdbc/unit/client/tls/MariaDbX509TrustingManagerTest.java
new file mode 100644
index 0000000..b8dd9f5
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/client/tls/MariaDbX509TrustingManagerTest.java
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.client.tls;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.client.tls.MariaDbX509TrustingManager;
+
+public class MariaDbX509TrustingManagerTest {
+
+  @Test
+  public void check() {
+    MariaDbX509TrustingManager trustingManager = new MariaDbX509TrustingManager();
+    assertNull(trustingManager.getAcceptedIssuers());
+    trustingManager.checkClientTrusted(null, null);
+    trustingManager.checkServerTrusted(null, null);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/plugin/AuthenticationPluginLoaderTest.java b/src/test/java/org/mariadb/jdbc/unit/plugin/AuthenticationPluginLoaderTest.java
new file mode 100644
index 0000000..9e58c84
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/plugin/AuthenticationPluginLoaderTest.java
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.plugin;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.SQLException;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.Configuration;
+import org.mariadb.jdbc.integration.Common;
+import org.mariadb.jdbc.plugin.AuthenticationPlugin;
+import org.mariadb.jdbc.plugin.authentication.AuthenticationPluginLoader;
+import org.mariadb.jdbc.plugin.authentication.standard.NativePasswordPlugin;
+
+public class AuthenticationPluginLoaderTest extends Common {
+
+  @Test
+  public void authenticationPluginLoaderTest() throws SQLException {
+    Configuration conf = Configuration.parse("jdbc:mariadb://localhost/");
+    AuthenticationPlugin authenticationPlugin =
+        AuthenticationPluginLoader.get("mysql_native_password", conf);
+    assertTrue(authenticationPlugin instanceof NativePasswordPlugin);
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> AuthenticationPluginLoader.get("UNKNOWN", conf),
+        "Client does not support authentication protocol requested by server");
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/plugin/TlsSocketPluginLoaderTest.java b/src/test/java/org/mariadb/jdbc/unit/plugin/TlsSocketPluginLoaderTest.java
new file mode 100644
index 0000000..1b416ee
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/plugin/TlsSocketPluginLoaderTest.java
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.plugin;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.sql.SQLException;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.integration.Common;
+import org.mariadb.jdbc.plugin.TlsSocketPlugin;
+import org.mariadb.jdbc.plugin.tls.TlsSocketPluginLoader;
+import org.mariadb.jdbc.plugin.tls.main.DefaultTlsSocketPlugin;
+
+public class TlsSocketPluginLoaderTest extends Common {
+
+  @Test
+  public void AuthenticationPluginLoaderTest() throws SQLException {
+    TlsSocketPlugin tlsSocketPlugin = TlsSocketPluginLoader.get("DEFAULT");
+    assertTrue(tlsSocketPlugin instanceof DefaultTlsSocketPlugin);
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> TlsSocketPluginLoader.get("UNKNOWN"),
+        "Client has not found any TLS factory plugin with name 'UNKNOWN'");
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/type/GeometryTest.java b/src/test/java/org/mariadb/jdbc/unit/type/GeometryTest.java
new file mode 100644
index 0000000..fb4b880
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/type/GeometryTest.java
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.type;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.SQLException;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.client.ColumnDecoder;
+import org.mariadb.jdbc.client.DataType;
+import org.mariadb.jdbc.client.ReadableByteBuf;
+import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
+import org.mariadb.jdbc.type.*;
+
+public class GeometryTest {
+
+  /* s must be an even-length string. */
+  public static byte[] hexStringToByteArray(String s1) {
+    String s = s1.replace(" ", "");
+    int len = s.length();
+    byte[] data = new byte[len / 2];
+    for (int i = 0; i < len; i += 2) {
+      data[i / 2] =
+          (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
+    }
+    return data;
+  }
+
+  @Test
+  public void testPointEncoding() throws SQLException {
+    byte[] ptBytes = hexStringToByteArray("000000000140000000000000004010000000000000");
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(ptBytes, ptBytes.length);
+    Geometry geo = Geometry.getGeometry(readBuf, ptBytes.length, null);
+    assertEquals("POINT(2.0 4.0)", geo.toString());
+    assertEquals(geo, geo);
+
+    assertEquals(new Point(2, 4), geo);
+    assertEquals(new Point(2, 4).hashCode(), geo.hashCode());
+    assertNotEquals("wrong", geo);
+    assertNotEquals(new Point(2, 5), geo);
+  }
+
+  @Test
+  public void testLineStringEncoding() throws SQLException {
+    String lineBigEndian =
+        "00"
+            + "00000002"
+            + "00000003"
+            + "0000000000000000"
+            + "0000000000000000"
+            + "00 00 00 00 00 00 00 00"
+            + "40 24 00 00 00 00 00 00"
+            + "40 24 00 00 00 00 00 00"
+            + "00 00 00 00 00 00 00 00";
+    byte[] lineBytes = hexStringToByteArray(lineBigEndian);
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(lineBytes, lineBytes.length);
+    Geometry geo = Geometry.getGeometry(readBuf, lineBytes.length, null);
+    assertEquals("LINESTRING(0.0 0.0,0.0 10.0,10.0 0.0)", geo.toString());
+    assertEquals(geo, geo);
+    assertEquals(
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true),
+        geo);
+    assertEquals(
+        new LineString(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true)
+            .hashCode(),
+        geo.hashCode());
+    assertNotEquals("wrong", geo);
+    assertNotEquals(
+        new LineString(new Point[] {new Point(1, 0), new Point(0, 10), new Point(10, 0)}, true),
+        geo);
+  }
+
+  @Test
+  public void testPolygonStringEncoding() throws SQLException {
+    String polygonBigEndian =
+        "00  "
+            + "00 00 00 03  "
+            + "00 00 00 01  "
+            + "00 00 00 07  "
+            + "3F F0 00 00 00 00 00 00  "
+            + "3F F0 00 00 00 00 00 00  "
+            + "3F F0 00 00 00 00 00 00  "
+            + "40 14 00 00 00 00 00 00  "
+            + "40 10 00 00 00 00 00 00  "
+            + "40 22 00 00 00 00 00 00  "
+            + "40 18 00 00 00 00 00 00  "
+            + "40 22 00 00 00 00 00 00  "
+            + "40 22 00 00 00 00 00 00  "
+            + "40 08 00 00 00 00 00 00  "
+            + "40 1C 00 00 00 00 00 00  "
+            + "40 00 00 00 00 00 00 00  "
+            + "3F F0 00 00 00 00 00 00  "
+            + "3F F0 00 00 00 00 00 00";
+    byte[] lineBytes = hexStringToByteArray(polygonBigEndian);
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(lineBytes, lineBytes.length);
+    Geometry geo = Geometry.getGeometry(readBuf, lineBytes.length, null);
+    assertEquals(
+        "POLYGON((1.0 1.0,1.0 5.0,4.0 9.0,6.0 9.0,9.0 3.0,7.0 2.0,1.0 1.0))", geo.toString());
+    assertEquals(geo, geo);
+    assertEquals(
+        new Polygon(
+            new LineString[] {
+              new LineString(
+                  new Point[] {
+                    new Point(1, 1),
+                    new Point(1, 5),
+                    new Point(4, 9),
+                    new Point(6, 9),
+                    new Point(9, 3),
+                    new Point(7, 2),
+                    new Point(1, 1)
+                  },
+                  false)
+            }),
+        geo);
+    assertEquals(
+        new Polygon(
+                new LineString[] {
+                  new LineString(
+                      new Point[] {
+                        new Point(1, 1),
+                        new Point(1, 5),
+                        new Point(4, 9),
+                        new Point(6, 9),
+                        new Point(9, 3),
+                        new Point(7, 2),
+                        new Point(1, 1)
+                      },
+                      false)
+                })
+            .hashCode(),
+        geo.hashCode());
+    assertNotEquals("wrong", geo);
+    assertNotEquals(
+        new Polygon(
+            new LineString[] {
+              new LineString(new Point[] {new Point(1, 1), new Point(1, 5), new Point(1, 1)}, false)
+            }),
+        geo);
+  }
+
+  @Test
+  public void testMultiPointEncoding() throws SQLException {
+    byte[] ptBytes =
+        hexStringToByteArray(
+            "00"
+                + "00 00 00 04"
+                + "00 00 00 03 "
+                + "00 "
+                + "00 00 00 01"
+                + "00 00 00 00 00 00 00 00"
+                + "00 00 00 00 00 00 00 00"
+                + "00 "
+                + "00 00 00 01"
+                + "00 00 00 00 00 00 00 00"
+                + "40 24 00 00 00 00 00 00"
+                + "00 "
+                + "00 00 00 01"
+                + "40 24 00 00 00 00 00 00"
+                + "00 00 00 00 00 00 00 00 ");
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(ptBytes, ptBytes.length);
+    Geometry geo = Geometry.getGeometry(readBuf, ptBytes.length, null);
+    assertEquals("MULTIPOINT(0.0 0.0,0.0 10.0,10.0 0.0)", geo.toString());
+    assertEquals(geo, geo);
+    assertEquals(
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}), geo);
+    assertEquals(
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)})
+            .hashCode(),
+        geo.hashCode());
+    assertNotEquals("wrong", geo);
+    assertNotEquals(
+        new MultiPoint(new Point[] {new Point(0, 0), new Point(0, 11), new Point(10, 0)}), geo);
+  }
+
+  @Test
+  public void testMultiLinestringEncoding() throws SQLException {
+    byte[] ptBytes =
+        hexStringToByteArray(
+            "00"
+                + "00 00 00 05"
+                + "00 00 00 01 "
+                + "00 "
+                + "00000002"
+                + "00000003"
+                + "00 00 00 00 00 00 00 00"
+                + "00 00 00 00 00 00 00 00"
+                + "00 00 00 00 00 00 00 00"
+                + "40 24 00 00 00 00 00 00"
+                + "40 24 00 00 00 00 00 00"
+                + "00 00 00 00 00 00 00 00");
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(ptBytes, ptBytes.length);
+    Geometry geo = Geometry.getGeometry(readBuf, ptBytes.length, null);
+    assertEquals("MULTILINESTRING((0.0 0.0,0.0 10.0,10.0 0.0))", geo.toString());
+    assertEquals(geo, geo);
+    MultiLineString ml =
+        new MultiLineString(
+            new LineString[] {
+              new LineString(
+                  new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true)
+            });
+    assertEquals(ml, geo);
+    assertEquals(ml.hashCode(), geo.hashCode());
+    assertFalse(geo.equals("wrong"));
+  }
+
+  @Test
+  public void testMultiPolygonEncoding() throws SQLException {
+    byte[] ptBytes =
+        hexStringToByteArray(
+            "00"
+                + "00 00 00 06"
+                + "00 00 00 01 "
+                + "00 "
+                + "00 00 00 03  "
+                + "00 00 00 01  "
+                + "00 00 00 07  "
+                + "3F F0 00 00 00 00 00 00  "
+                + "3F F0 00 00 00 00 00 00  "
+                + "3F F0 00 00 00 00 00 00  "
+                + "40 14 00 00 00 00 00 00  "
+                + "40 10 00 00 00 00 00 00  "
+                + "40 22 00 00 00 00 00 00  "
+                + "40 18 00 00 00 00 00 00  "
+                + "40 22 00 00 00 00 00 00  "
+                + "40 22 00 00 00 00 00 00  "
+                + "40 08 00 00 00 00 00 00  "
+                + "40 1C 00 00 00 00 00 00  "
+                + "40 00 00 00 00 00 00 00  "
+                + "3F F0 00 00 00 00 00 00  "
+                + "3F F0 00 00 00 00 00 00");
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(ptBytes, ptBytes.length);
+    Geometry geo = Geometry.getGeometry(readBuf, ptBytes.length, null);
+    assertEquals(
+        "MULTIPOLYGON(((1.0 1.0,1.0 5.0,4.0 9.0,6.0 9.0,9.0 3.0,7.0 2.0,1.0 1.0)))",
+        geo.toString());
+    assertEquals(geo, geo);
+    MultiPolygon ml =
+        new MultiPolygon(
+            new Polygon[] {
+              new Polygon(
+                  new LineString[] {
+                    new LineString(
+                        new Point[] {
+                          new Point(1, 1),
+                          new Point(1, 5),
+                          new Point(4, 9),
+                          new Point(6, 9),
+                          new Point(9, 3),
+                          new Point(7, 2),
+                          new Point(1, 1)
+                        },
+                        false)
+                  })
+            });
+    assertEquals(ml, geo);
+    assertEquals(ml.hashCode(), geo.hashCode());
+    assertFalse(geo.equals("wrong"));
+  }
+
+  @Test
+  public void testMultiGeoEncoding() throws SQLException {
+    byte[] ptBytes =
+        hexStringToByteArray(
+            "00"
+                + "00 00 00 07"
+                + "00 00 00 02 "
+                + "00 "
+                + "00 00 00 01"
+                + "40 00 00 00 00 00 00 00 "
+                + "40 10 00 00 00 00 00 00"
+                + "00"
+                + "00000002"
+                + "00000003"
+                + "0000000000000000"
+                + "0000000000000000"
+                + "00 00 00 00 00 00 00 00"
+                + "40 24 00 00 00 00 00 00"
+                + "40 24 00 00 00 00 00 00"
+                + "00 00 00 00 00 00 00 00");
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(ptBytes, ptBytes.length);
+    Geometry geo = Geometry.getGeometry(readBuf, ptBytes.length, null);
+    assertEquals(
+        "GEOMETRYCOLLECTION(POINT(2.0 4.0),LINESTRING(0.0 0.0,0.0 10.0,10.0 0.0))", geo.toString());
+    GeometryCollection geo1 =
+        new GeometryCollection(
+            new Geometry[] {
+              new Point(2, 4),
+              new LineString(
+                  new Point[] {new Point(0, 0), new Point(0, 10), new Point(10, 0)}, true)
+            });
+    assertEquals(geo1, geo);
+  }
+
+  @Test
+  public void testWrongEncoding() throws SQLException {
+    byte[] ptBytes = hexStringToByteArray("00 00 00 00 08");
+    ReadableByteBuf readBuf = new StandardReadableByteBuf(ptBytes, ptBytes.length);
+    assertThrows(
+        SQLException.class,
+        () ->
+            Geometry.getGeometry(
+                readBuf, ptBytes.length, ColumnDecoder.create("test", DataType.GEOMETRY, 0)));
+    assertNull(Geometry.getGeometry(new StandardReadableByteBuf(new byte[0], 0), 0, null));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/ClientParserTest.java b/src/test/java/org/mariadb/jdbc/unit/util/ClientParserTest.java
new file mode 100644
index 0000000..824f0d2
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/ClientParserTest.java
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.nio.charset.StandardCharsets;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.ClientParser;
+
+@SuppressWarnings("ConstantConditions")
+public class ClientParserTest {
+
+  private void parse(String sql, String[] expected, String[] expectedNoBackSlash) {
+    ClientParser parser = ClientParser.parameterParts(sql, false);
+    assertEquals(expected.length, parser.getParamCount() + 1, displayErr(parser, expected));
+
+    int pos = 0;
+    int paramPos = parser.getQuery().length;
+    for (int i = 0; i < parser.getParamCount(); i++) {
+      paramPos = parser.getParamPositions().get(i);
+      assertEquals(expected[i], new String(parser.getQuery(), pos, paramPos - pos));
+      pos = paramPos + 1;
+    }
+    assertEquals(expected[expected.length - 1], new String(parser.getQuery(), pos, paramPos - pos));
+
+    parser = ClientParser.parameterParts(sql, true);
+    assertEquals(
+        expectedNoBackSlash.length, parser.getParamCount() + 1, displayErr(parser, expected));
+    pos = 0;
+    paramPos = parser.getQuery().length;
+    for (int i = 0; i < parser.getParamCount(); i++) {
+      paramPos = parser.getParamPositions().get(i);
+      assertEquals(expectedNoBackSlash[i], new String(parser.getQuery(), pos, paramPos - pos));
+      pos = paramPos + 1;
+    }
+    assertEquals(
+        expectedNoBackSlash[expectedNoBackSlash.length - 1],
+        new String(parser.getQuery(), pos, paramPos - pos));
+  }
+
+  private String displayErr(ClientParser parser, String[] exp) {
+    StringBuilder sb = new StringBuilder();
+    sb.append("is:\n");
+
+    int pos = 0;
+    int paramPos = parser.getQuery().length;
+    for (int i = 0; i < parser.getParamCount(); i++) {
+      paramPos = parser.getParamPositions().get(i);
+      sb.append(new String(parser.getQuery(), pos, paramPos - pos, StandardCharsets.UTF_8))
+          .append("\n");
+      pos = paramPos + 1;
+    }
+    sb.append(new String(parser.getQuery(), pos, paramPos - pos));
+
+    sb.append("but was:\n");
+    for (String s : exp) {
+      sb.append(s).append("\n");
+    }
+    return sb.toString();
+  }
+
+  @Test
+  public void ClientParser() {
+    parse(
+        "SELECT '\\\\test' /*test* #/ ;`*/",
+        new String[] {"SELECT '\\\\test' /*test* #/ ;`*/"},
+        new String[] {"SELECT '\\\\test' /*test* #/ ;`*/"});
+    parse(
+        "DO '\\\"', \"\\'\"",
+        new String[] {"DO '\\\"', \"\\'\""},
+        new String[] {"DO '\\\"', \"\\'\""});
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/ConfigurationTest.java b/src/test/java/org/mariadb/jdbc/unit/util/ConfigurationTest.java
new file mode 100644
index 0000000..25737e4
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/ConfigurationTest.java
@@ -0,0 +1,888 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.*;
+import org.mariadb.jdbc.export.HaMode;
+import org.mariadb.jdbc.export.SslMode;
+import org.mariadb.jdbc.integration.Common;
+
+@SuppressWarnings("ConstantConditions")
+public class ConfigurationTest {
+
+  @Test
+  public void testWrongFormat() {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> Configuration.parse("jdbc:mariadb:/localhost/test"),
+        "url parsing error : '//' is not present in the url");
+  }
+
+  @Test
+  public void testParseProps() throws SQLException {
+    Configuration conf = Configuration.parse("jdbc:mariadb://localhost/test", null);
+    assertEquals(0, conf.socketTimeout());
+
+    Properties props = new Properties();
+    props.setProperty("socketTimeout", "50");
+    conf = Configuration.parse("jdbc:mariadb://localhost/test", props);
+    assertEquals(50, conf.socketTimeout());
+  }
+
+  @Test
+  public void testCredentialType() throws SQLException {
+    Configuration conf = Configuration.parse("jdbc:mariadb://localhost/test?credentialType=");
+    assertNull(conf.credentialPlugin());
+  }
+
+  @Test
+  public void testWrongHostFormat() {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> Configuration.parse("jdbc:mariadb://localhost:wrongPort/test"),
+        "Incorrect port value : wrongPort");
+  }
+
+  @Test
+  public void testNoAdditionalPart() throws SQLException {
+    assertEquals(null, Configuration.parse("jdbc:mariadb://localhost/").database());
+    assertEquals(null, Configuration.parse("jdbc:mariadb://localhost/?socketTimeout=50").user());
+    assertEquals(null, Configuration.parse("jdbc:mariadb://localhost").database());
+    assertEquals(null, Configuration.parse("jdbc:mariadb://localhost").user());
+    assertEquals(
+        50,
+        Configuration.parse("jdbc:mariadb://localhost?socketTimeout=50&file=/tmp/test")
+            .socketTimeout());
+    assertEquals(null, Configuration.parse("jdbc:mariadb://localhost?").user());
+  }
+
+  @Test
+  public void testAliases() throws SQLException {
+    assertEquals(
+        "someCipher",
+        Configuration.parse("jdbc:mariadb://localhost/?enabledSSLCipherSuites=someCipher")
+            .enabledSslCipherSuites());
+    assertEquals(
+        "/tmp/path",
+        Configuration.parse("jdbc:mariadb://localhost/?serverRSAPublicKeyFile=/tmp/path")
+            .serverRsaPublicKeyFile());
+  }
+
+  @Test
+  public void testDatabaseOnly() throws SQLException {
+    assertEquals("DB", Configuration.parse("jdbc:mariadb://localhost/DB").database());
+    assertEquals(null, Configuration.parse("jdbc:mariadb://localhost/DB").user());
+  }
+
+  @Test
+  public void testUrl() throws SQLException {
+    Configuration conf =
+        new Configuration.Builder()
+            .database("DB")
+            .addHost("local", 3306, true)
+            .haMode(HaMode.REPLICATION)
+            .build();
+    assertEquals("jdbc:mariadb:replication://local/DB", conf.initialUrl());
+    assertEquals("jdbc:mariadb:replication://local/DB", conf.toString());
+    assertEquals(
+        Configuration.parse(
+            "jdbc:mariadb:replication://address=(host=local)(port=3306)(type=primary)/DB"),
+        conf);
+
+    conf =
+        new Configuration.Builder()
+            .database("DB")
+            .addresses(
+                HostAddress.from("local", 3306, true), HostAddress.from("host2", 3307, false))
+            .haMode(HaMode.REPLICATION)
+            .build();
+
+    assertEquals("jdbc:mariadb:replication://local,host2:3307/DB", conf.initialUrl());
+
+    conf =
+        new Configuration.Builder()
+            .database("DB")
+            .addHost("local", 3306, true)
+            .haMode(HaMode.REPLICATION)
+            .socketTimeout(50)
+            .build();
+    assertEquals("jdbc:mariadb:replication://local/DB?socketTimeout=50", conf.initialUrl());
+
+    conf =
+        new Configuration.Builder()
+            .database("DB")
+            .addHost("local", 3306)
+            .addHost("local", 3307)
+            .addHost("local", 3308)
+            .haMode(HaMode.REPLICATION)
+            .socketTimeout(50)
+            .build();
+    assertEquals(
+        "jdbc:mariadb:replication://local,local:3307,local:3308/DB?socketTimeout=50",
+        conf.initialUrl());
+
+    conf =
+        new Configuration.Builder()
+            .database("DB")
+            .addHost("local", 3306)
+            .addHost("local", 3307)
+            .addHost("local", 3308)
+            .haMode(HaMode.LOADBALANCE)
+            .socketTimeout(50)
+            .build();
+    assertEquals(
+        "jdbc:mariadb:loadbalance://address=(host=local)(port=3306)(type=primary),address=(host=local)(port=3307)(type=primary),address=(host=local)(port=3308)(type=primary)/DB?socketTimeout=50",
+        conf.initialUrl());
+
+    conf =
+        new Configuration.Builder()
+            .database("DB")
+            .addHost("local", 3306, true)
+            .haMode(HaMode.REPLICATION)
+            .autocommit(false)
+            .build();
+    assertEquals("jdbc:mariadb:replication://local/DB?autocommit=false", conf.initialUrl());
+  }
+
+  @Test
+  public void testAcceptsUrl() {
+    Driver driver = new Driver();
+    assertFalse(driver.acceptsURL(null));
+    assertTrue(driver.acceptsURL("jdbc:mariadb://localhost/test"));
+    assertFalse(driver.acceptsURL("jdbc:mysql://localhost/test"));
+    assertTrue(driver.acceptsURL("jdbc:mysql://localhost/test?permitMysqlScheme"));
+  }
+
+  @Test
+  public void testConfigurationIsolation() throws Throwable {
+    Configuration conf =
+        Configuration.parse("jdbc:mariadb://localhost/test?transactionIsolation=REPEATABLE-READ");
+    assertTrue(TransactionIsolation.REPEATABLE_READ == conf.transactionIsolation());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test");
+    assertNull(conf.transactionIsolation());
+
+    conf =
+        Configuration.parse("jdbc:mariadb://localhost/test?transactionIsolation=repeatable-read");
+    assertTrue(TransactionIsolation.REPEATABLE_READ == conf.transactionIsolation());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?transactionIsolation=readCommitted");
+    assertTrue(TransactionIsolation.READ_COMMITTED == conf.transactionIsolation());
+
+    conf =
+        Configuration.parse("jdbc:mariadb://localhost/test?transactionIsolation=READ-UNCOMMITTED");
+    assertTrue(TransactionIsolation.READ_UNCOMMITTED == conf.transactionIsolation());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?transactionIsolation=SERIALIZABLE");
+    assertTrue(TransactionIsolation.SERIALIZABLE == conf.transactionIsolation());
+
+    try {
+      Configuration.parse("jdbc:mariadb://localhost/test?transactionIsolation=wrong_val");
+      Assertions.fail();
+    } catch (SQLException e) {
+      assertTrue(
+          e.getMessage().contains("Wrong argument value 'wrong_val' for TransactionIsolation"));
+    }
+
+    Assertions.assertNull(
+        Configuration.parse("jdbc:mysql://localhost/test?transactionIsolation=wrong_val"));
+
+    conf =
+        Configuration.parse(
+            "jdbc:mysql://localhost/test?transactionIsolation=SERIALIZABLE&permitMysqlScheme");
+    assertTrue(TransactionIsolation.SERIALIZABLE == conf.transactionIsolation());
+  }
+
+  @Test
+  public void testSslAlias() throws Throwable {
+    Configuration conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode=verify-full");
+    assertTrue(SslMode.VERIFY_FULL == conf.sslMode());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode=verify_full");
+    assertTrue(SslMode.VERIFY_FULL == conf.sslMode());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode=trust");
+    assertTrue(SslMode.TRUST == conf.sslMode());
+
+    try {
+      Configuration.parse("jdbc:mariadb://localhost/test?sslMode=wrong_trust");
+      Assertions.fail();
+    } catch (SQLException e) {
+      assertTrue(e.getMessage().contains("Wrong argument value 'wrong_trust' for SslMode"));
+    }
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode=verify-ca");
+    assertTrue(SslMode.VERIFY_CA == conf.sslMode());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test");
+    assertTrue(SslMode.DISABLE == conf.sslMode());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode");
+    assertTrue(SslMode.DISABLE == conf.sslMode());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode=0");
+    assertTrue(SslMode.DISABLE == conf.sslMode());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode=1");
+    assertTrue(SslMode.VERIFY_FULL == conf.sslMode());
+
+    conf = Configuration.parse("jdbc:mariadb://localhost/test?sslMode=true");
+    assertTrue(SslMode.VERIFY_FULL == conf.sslMode());
+  }
+
+  @Test
+  public void testSslCompatibility() throws Throwable {
+    assertEquals(
+        SslMode.VERIFY_FULL, Configuration.parse("jdbc:mariadb://localhost/test?useSsl").sslMode());
+    assertEquals(
+        SslMode.VERIFY_FULL,
+        Configuration.parse("jdbc:mariadb://localhost/test?useSsl=true").sslMode());
+    assertEquals(
+        SslMode.VERIFY_FULL,
+        Configuration.parse("jdbc:mariadb://localhost/test?useSsl=1").sslMode());
+    assertEquals(
+        SslMode.VERIFY_FULL,
+        Configuration.parse("jdbc:mariadb://localhost/test?useSSL=1").sslMode());
+    assertEquals(
+        SslMode.TRUST,
+        Configuration.parse("jdbc:mariadb://localhost/test?useSsl&trustServerCertificate")
+            .sslMode());
+    assertEquals(
+        SslMode.VERIFY_CA,
+        Configuration.parse("jdbc:mariadb://localhost/test?useSsl&disableSslHostnameVerification")
+            .sslMode());
+  }
+
+  @Test
+  public void testBooleanDefault() throws Throwable {
+    assertFalse(
+        Configuration.parse("jdbc:mariadb:///test").includeThreadDumpInDeadlockExceptions());
+    assertFalse(
+        Configuration.parse("jdbc:mariadb:///test?includeThreadDumpInDeadlockExceptions=false")
+            .includeThreadDumpInDeadlockExceptions());
+    assertTrue(
+        Configuration.parse("jdbc:mariadb:///test?includeThreadDumpInDeadlockExceptions=true")
+            .includeThreadDumpInDeadlockExceptions());
+    assertTrue(
+        Configuration.parse("jdbc:mariadb:///test?includeThreadDumpInDeadlockExceptions")
+            .includeThreadDumpInDeadlockExceptions());
+  }
+
+  @Test
+  public void testOptionTakeDefault() throws Throwable {
+    Configuration conf = Configuration.parse("jdbc:mariadb://localhost/test");
+    assertEquals(30_000, conf.connectTimeout());
+    assertEquals(250, conf.prepStmtCacheSize());
+    assertNull(conf.user());
+    assertEquals(0, conf.socketTimeout());
+    int initialLoginTimeout = DriverManager.getLoginTimeout();
+    DriverManager.setLoginTimeout(60);
+    conf = Configuration.parse("jdbc:mariadb://localhost/test");
+    assertEquals(60_000, conf.connectTimeout());
+    DriverManager.setLoginTimeout(initialLoginTimeout);
+  }
+
+  @Test
+  public void testOptionParse() throws Throwable {
+    Configuration conf =
+        Configuration.parse(
+            "jdbc:mariadb://localhost/test?user=root&password=toto&createDB=true"
+                + "&autoReconnect=true&prepStmtCacheSize=2&connectTimeout=5&socketTimeout=20");
+    assertEquals(5, conf.connectTimeout());
+    assertEquals(20, conf.socketTimeout());
+    assertEquals(2, conf.prepStmtCacheSize());
+    assertEquals("true", conf.nonMappedOptions().get("createDB"));
+    assertEquals("true", conf.nonMappedOptions().get("autoReconnect"));
+    assertEquals("root", conf.user());
+    assertEquals("toto", conf.password());
+  }
+
+  @Test
+  public void nonCaseSensitiveOptions() throws Throwable {
+    Configuration conf =
+        Configuration.parse(
+            "jdbc:mariadb://localhost/test?useR=root&paSsword=toto&createdb=true"
+                + "&autoReConnect=true&prepStMtCacheSize=2&ConnectTimeout=5&socketTimeout=20");
+    assertEquals(5, conf.connectTimeout());
+    assertEquals(20, conf.socketTimeout());
+    assertEquals(2, conf.prepStmtCacheSize());
+    assertEquals("true", conf.nonMappedOptions().get("createdb"));
+    assertEquals("true", conf.nonMappedOptions().get("autoReConnect"));
+    assertEquals("root", conf.user());
+    assertEquals("toto", conf.password());
+  }
+
+  @Test
+  public void wrongTypeParsing() {
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> Configuration.parse("jdbc:mariadb://localhost/test?socketTimeout=20aa"),
+        "Optional parameter socketTimeout must be Integer, was '20aa'");
+  }
+
+  @Test
+  public void testOptionParseSlash() throws Throwable {
+    Configuration jdbc =
+        Configuration.parse(
+            "jdbc:mariadb://127.0.0.1:3306/colleo?user=root&password=toto"
+                + "&localSocket=/var/run/mysqld/mysqld.sock");
+    assertEquals("/var/run/mysqld/mysqld.sock", jdbc.localSocket());
+    assertEquals("root", jdbc.user());
+    assertEquals("toto", jdbc.password());
+  }
+
+  @Test
+  public void testOptionParseIntegerMinimum() throws Throwable {
+    Configuration jdbc =
+        Configuration.parse(
+            "jdbc:mariadb://localhost/test?user=root&autoReconnect=true"
+                + "&prepStmtCacheSize=240&connectTimeout=5");
+    assertEquals(5, jdbc.connectTimeout());
+    assertEquals(240, jdbc.prepStmtCacheSize());
+  }
+
+  @Test
+  public void testWithoutDb() throws Throwable {
+    Configuration jdbc =
+        Configuration.parse("jdbc:mariadb://localhost/?user=root&tcpKeepAlive=true");
+    assertTrue(jdbc.tcpKeepAlive());
+    assertNull(jdbc.database());
+
+    Configuration jdbc2 =
+        Configuration.parse("jdbc:mariadb://localhost?user=root&tcpKeepAlive=true");
+    assertTrue(jdbc2.tcpKeepAlive());
+    assertNull(jdbc2.database());
+  }
+
+  @Test
+  public void testOptionParseIntegerNotPossible() {
+    assertThrows(
+        SQLException.class,
+        () ->
+            Configuration.parse(
+                "jdbc:mariadb://localhost/test?user=root&autoReconnect=true&prepStmtCacheSize=-2"
+                    + "&connectTimeout=5"));
+  }
+
+  @Test()
+  public void testJdbcParserSimpleIpv4basic() throws SQLException {
+    String url = "jdbc:mariadb://master:3306,slave1:3307,slave2:3308/database";
+    Configuration conf = Configuration.parse(url);
+    assertEquals("jdbc:mariadb://master,slave1:3307,slave2:3308/database", conf.initialUrl());
+    url =
+        "jdbc:mariadb://address=(host=master)(port=3306)(type=primary),address=(host=slave1)(port=3307)(type=replica),address=(host=slave2)(port=3308)(type=replica)/database";
+    conf = Configuration.parse(url);
+    assertEquals(
+        "jdbc:mariadb://master,address=(host=slave1)(port=3307)(type=replica),address=(host=slave2)(port=3308)(type=replica)/database",
+        conf.initialUrl());
+    url =
+        "jdbc:mariadb://address=(host=master)(port=3306)(type=master),address=(host=slave1)(port=3307)(type=replica),address=(host=slave2)(port=3308)(type=replica)/database";
+    conf = Configuration.parse(url);
+    assertEquals(
+        "jdbc:mariadb://master,address=(host=slave1)(port=3307)(type=replica),address=(host=slave2)(port=3308)(type=replica)/database",
+        conf.initialUrl());
+    url = "jdbc:mariadb:replication://master:3306,slave1:3307,slave2:3308/database";
+    conf = Configuration.parse(url);
+    assertEquals(
+        "jdbc:mariadb:replication://master,slave1:3307,slave2:3308/database", conf.initialUrl());
+  }
+
+  @Test
+  public void testJdbcParserSimpleIpv4basicError() throws SQLException {
+    Configuration Configuration = org.mariadb.jdbc.Configuration.parse(null);
+    assertTrue(Configuration == null);
+  }
+
+  @Test
+  public void testJdbcParserSimpleIpv4basicwithoutDatabase() throws SQLException {
+    String url = "jdbc:mariadb://master:3306,slave1:3307,slave2:3308/";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertNull(conf.database());
+    assertNull(conf.user());
+    assertNull(conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3308, true), conf.addresses().get(2));
+  }
+
+  @Test
+  public void testJdbcParserWithoutDatabaseWithProperties() throws SQLException {
+    String url = "jdbc:mariadb://master:3306,slave1:3307,slave2:3308?autoReconnect=true";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertNull(conf.database());
+    assertNull(conf.user());
+    assertNull(conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3308, true), conf.addresses().get(2));
+  }
+
+  @Test
+  public void testJdbcParserWithoutDatabase2WithProperties() throws SQLException {
+    String url = "jdbc:mariadb://master:3306,slave1:3307,slave2:3308/?autoReconnect=true";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertNull(conf.database());
+    assertNull(conf.user());
+    assertNull(conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3308, true), conf.addresses().get(2));
+  }
+
+  @Test
+  public void testJdbcParserSimpleIpv4Properties() throws SQLException {
+    String url = "jdbc:mariadb://master:3306,slave1:3307,slave2:3308/database?autoReconnect=true";
+
+    Properties prop = new Properties();
+    prop.setProperty("user", "greg");
+    prop.setProperty("password", "pass");
+    prop.setProperty("allowMultiQueries", "true");
+
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url, prop);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertTrue(conf.allowMultiQueries());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3308, true), conf.addresses().get(2));
+
+    prop = new Properties();
+    prop.put("user", "greg");
+    prop.put("password", "pass");
+    prop.put("allowMultiQueries", true);
+
+    conf = org.mariadb.jdbc.Configuration.parse(url, prop);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertTrue(conf.allowMultiQueries());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3308, true), conf.addresses().get(2));
+  }
+
+  @Test
+  public void testJdbcParserBooleanOption() {
+    String url = "jdbc:mariadb://master:3306,slave1:3307,slave2:3308?autoReconnect=truee";
+    Properties prop = new Properties();
+    prop.setProperty("user", "greg");
+    prop.setProperty("password", "pass");
+    try {
+      Configuration.parse(url, prop);
+    } catch (SQLException sqle) {
+      assertTrue(
+          sqle.getMessage()
+              .contains(
+                  "Optional parameter autoReconnect must be boolean (true/false or 0/1) was"
+                      + " \"truee\""));
+    }
+  }
+
+  @Test
+  public void testJdbcParserSimpleIpv4() throws SQLException {
+    String url =
+        "jdbc:mariadb://master:3306,slave1:3307,slave2:3308/database?user=greg&password=pass";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3308, true), conf.addresses().get(2));
+  }
+
+  @Test
+  public void testJdbcParserSimpleIpv6() throws SQLException {
+    String url =
+        "jdbc:mariadb://[2001:0660:7401:0200:0000:0000:0edf:bdd7],[2001:660:7401:200::edf:bdd7]:3307,[2001:660:7401:200::edf:bdd7]-test"
+            + "/database?user=greg&password=pass";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(
+        HostAddress.from("2001:0660:7401:0200:0000:0000:0edf:bdd7", 3306, true),
+        conf.addresses().get(0));
+    assertEquals(
+        HostAddress.from("2001:660:7401:200::edf:bdd7", 3307, true), conf.addresses().get(1));
+    assertEquals(
+        HostAddress.from("2001:660:7401:200::edf:bdd7", 3306, true), conf.addresses().get(2));
+  }
+
+  @Test
+  public void testJdbcParserParameter() throws SQLException {
+    String url =
+        "jdbc:mariadb://address=(type=primary)(port=3306)(host=master1),address=(port=3307)(type=primary)"
+            + "(host=master2)(type=replica),address=(type=slave)(host=slave1)(port=3308)/database?user=greg&password=pass";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master1", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("master2", 3307, false), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave1", 3308, false), conf.addresses().get(2));
+
+    url =
+        "jdbc:mariadb://address=(port=3306)(host=master1),address=(port=3307)"
+            + "(host=master2),address=(host=master3)(port=3308)/database?user=greg&password=pass";
+    conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master1", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("master2", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("master3", 3308, true), conf.addresses().get(2));
+
+    url =
+        "jdbc:mariadb:replication://address=(port=3306)(host=master1),address=(port=3307)(host=slave1)"
+            + " ,address=(host=slave2)(port=3308)(other=5/database?user=greg&password=pass";
+    conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master1", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3307, false), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3308, false), conf.addresses().get(2));
+  }
+
+  @Test
+  public void address() {
+    assertEquals("address=(host=test)(port=3306)", HostAddress.from("test", 3306).toString());
+    assertEquals(
+        "address=(host=test)(port=3306)(type=replica)",
+        HostAddress.from("test", 3306, false).toString());
+    assertEquals(
+        "address=(host=test)(port=3306)(type=primary)",
+        HostAddress.from("test", 3306, true).toString());
+  }
+
+  @Test
+  public void hostAddressEqual() {
+    HostAddress host = HostAddress.from("test", 3306);
+    assertEquals(host, host);
+    assertNotEquals(null, host);
+    assertEquals(HostAddress.from("test", 3306), host);
+    assertNotEquals("", host);
+    assertNotEquals(HostAddress.from("test2", 3306, true), host);
+    assertNotEquals(HostAddress.from("test", 3306, true), host);
+    assertNotEquals(HostAddress.from("test", 3306, false), host);
+  }
+
+  @Test
+  public void testJdbcParserParameterErrorEqual() {
+    String wrongIntVal = "jdbc:mariadb://localhost?socketTimeout=blabla";
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> Configuration.parse(wrongIntVal),
+        "Optional parameter socketTimeout must be Integer, was 'blabla'");
+    String wrongBoolVal = "jdbc:mariadb://localhost?autocommit=blabla";
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> Configuration.parse(wrongBoolVal),
+        "Optional parameter autocommit must be boolean (true/false or 0/1)");
+    String url =
+        "jdbc:mariadb://address=(type=)(port=3306)(host=master1),address=(port=3307)(type=primary)"
+            + "(host=master2),address=(type=replica)(host=slave1)(port=3308)/database?user=greg&password=pass";
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> Configuration.parse(url),
+        "Invalid connection URL, expected key=value pairs, found (type=)");
+    String url2 =
+        "jdbc:mariadb://address=(type=wrong)(port=3306)(host=master1),address=(port=3307)(type=primary)"
+            + "(host=master2),address=(type=replica)(host=slave1)(port=3308)/database?user=greg&password=pass";
+    Common.assertThrowsContains(
+        SQLException.class,
+        () -> Configuration.parse(url2),
+        "Wrong type value (type=wrong) (possible value primary/replica)");
+  }
+
+  @Test
+  public void testJdbcParserHaModeNone() throws SQLException {
+    String url = "jdbc:mariadb://localhost/database";
+    Configuration jdbc = Configuration.parse(url);
+    assertTrue(jdbc.haMode().equals(HaMode.NONE));
+  }
+
+  @Test
+  public void testJdbcParserHaModeLoadReplication() throws SQLException {
+    String url = "jdbc:mariadb:replication://localhost/database";
+    Configuration jdbc = Configuration.parse(url);
+    assertTrue(jdbc.haMode().equals(HaMode.REPLICATION));
+  }
+
+  @Test
+  public void testJdbcParserReplicationParameter() throws SQLException {
+    String url =
+        "jdbc:mariadb:replication://address=(type=primary)(port=3306)(host=master1),address=(port=3307)"
+            + "(type=primary)(host=master2),address=(type=replica)(host=slave1)(port=3308)/database"
+            + "?user=greg&password=pass&pinGlobalTxToPhysicalConnection&servicePrincipalName=BLA"
+            + "&allowPublicKeyRetrieval&serverRSAPublicKeyFile=/tmp/path";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertEquals("database", conf.database());
+    assertEquals("greg", conf.user());
+    assertEquals("pass", conf.password());
+    assertEquals("BLA", conf.servicePrincipalName());
+    assertTrue(conf.allowPublicKeyRetrieval());
+    assertEquals("/tmp/path", conf.serverRsaPublicKeyFile());
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master1", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("master2", 3307, true), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave1", 3308, false), conf.addresses().get(2));
+  }
+
+  @Test
+  public void testJdbcParserReplicationParameterWithoutType() throws SQLException {
+    String url = "jdbc:mariadb:replication://master1,slave1,slave2/database";
+    Configuration conf = org.mariadb.jdbc.Configuration.parse(url);
+    assertEquals(3, conf.addresses().size());
+    assertEquals(HostAddress.from("master1", 3306, true), conf.addresses().get(0));
+    assertEquals(HostAddress.from("slave1", 3306, false), conf.addresses().get(1));
+    assertEquals(HostAddress.from("slave2", 3306, false), conf.addresses().get(2));
+  }
+
+  /**
+   * Conj-167 : Driver is throwing IllegalArgumentException instead of returning null.
+   *
+   * @throws SQLException if any exception occur
+   */
+  @Test
+  public void checkOtherDriverCompatibility() throws SQLException {
+    Configuration jdbc = Configuration.parse("jdbc:h2:mem:RZM;DB_CLOSE_DELAY=-1");
+    assertTrue(jdbc == null);
+  }
+
+  @Test
+  public void checkDisable() throws SQLException {
+    Configuration jdbc = Configuration.parse("jdbc:mysql://localhost/test");
+    assertTrue(jdbc == null);
+  }
+
+  @Test
+  public void loginTimeout() throws SQLException {
+    Configuration jdbc = Configuration.parse("jdbc:mariadb://localhost/test");
+    assertEquals(30000, jdbc.connectTimeout());
+
+    DriverManager.setLoginTimeout(10);
+    jdbc = Configuration.parse("jdbc:mariadb://localhost/test");
+    assertEquals(10000, jdbc.connectTimeout());
+
+    jdbc = Configuration.parse("jdbc:mariadb://localhost/test?connectTimeout=5000");
+    assertEquals(5000, jdbc.connectTimeout());
+    DriverManager.setLoginTimeout(0);
+
+    jdbc = Configuration.parse("jdbc:mariadb://localhost/test?connectTimeout=5000");
+    assertEquals(5000, jdbc.connectTimeout());
+  }
+
+  @Test
+  public void checkHaMode() throws SQLException {
+    checkHaMode("jdbc:mariadb://localhost/test", HaMode.NONE);
+    checkHaMode("jdbc:mariadb:replication://localhost/test", HaMode.REPLICATION);
+    checkHaMode("jdbc:mariadb:replication//localhost/test", HaMode.REPLICATION);
+    checkHaMode("jdbc:mariadb:failover://localhost:3306/test", HaMode.LOADBALANCE);
+    checkHaMode("jdbc:mariadb:loadbalance://localhost:3306/test", HaMode.LOADBALANCE);
+
+    try {
+      checkHaMode("jdbc:mariadb:replicati//localhost/test", HaMode.REPLICATION);
+      fail();
+    } catch (SQLException sqle) {
+      assertTrue(
+          sqle.getMessage().contains("wrong failover parameter format in connection String"));
+    }
+  }
+
+  private void checkHaMode(String url, HaMode expectedHaMode) throws SQLException {
+    Configuration jdbc = Configuration.parse(url);
+    assertEquals(expectedHaMode, jdbc.haMode());
+  }
+
+  /**
+   * CONJ-452 : correcting line break in connection url.
+   *
+   * @throws SQLException if any exception occur
+   */
+  @Test
+  public void checkInfileCertificate() throws SQLException {
+    String url =
+        "jdbc:mariadb://1.2.3.4/testj?user=diego"
+            + "&autocommit=true&serverSslCert="
+            + "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDITCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQUFADBIMSMwIQYDVQQDExpHb29n\n"
+            + "bGUgQ2xvdWQgU1FMIFNlcnZlciBDQTEUMBIGA1UEChMLR29vZ2xlLCBJbmMxCzAJ\n"
+            + "BgNVBAYTAlVTMB4XDTE3MDQyNzEyMjcyNFoXDTE5MDQyNzEyMjgyNFowSDEjMCEG\n"
+            + "A1UEAxMaR29vZ2xlIENsb3VkIFNRTCBTZXJ2ZXIgQ0ExFDASBgNVBAoTC0dvb2ds\n"
+            + "ZSwgSW5jMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n"
+            + "ggEBANA6vS37//gvYOsEXKA9Cnlt/C1Ef/a5zJNahpVxx8HbJn6DF+pQbhHm3o4P\n"
+            + "TeZp1HoRg5TRiXOEkNTBmgSQbR2+otM2q2gmkn4XAh0+yXkNW3hr2IydJyg9C26v\n"
+            + "/OzFvuLcw9iDBvrn433pDa6vjYDU+wiQaVtr1ItzsoE/kgW2IkgFVQB+CrkpAmwm\n"
+            + "omwEze3QFUUznP0PHy3P7g7UVD9u5x3APY6kVt2dq8mnOiLZkyfHHR2j6+j0E73I\n"
+            + "k3HQv7D0yRIv3kuNpFgJbITVgDIq9ukWU2XinDHUjguCDH+yQAoQH7hOQlWUHIz8\n"
+            + "/TtfZjrlUQf2uLzOWCn5KxfEqTkCAwEAAaMWMBQwEgYDVR0TAQH/BAgwBgEB/wIB\n"
+            + "ADANBgkqhkiG9w0BAQUFAAOCAQEArYkBkUvMvteT4fN6lxUkzmp8R7clLPkA2HnJ\n"
+            + "7IUK3c5GJ0/blffxj/9Oe2g+etga15SIO73GNAnTxhxIJllKRmmh6SR+dwNMkAvE\n"
+            + "xp87/Y6cSeJp5d4HhZUvxpFjaUDsWIC8tpbriUJoqGIirprLVcsPgDjKyuvVOlbK\n"
+            + "aQf3fOoBPLspGWHgic8Iw1O4kRcStUGCSCwOtYcgMJEhVqTgX0sTX5BgatZhr8FY\n"
+            + "Mnoceo2vzzxgHJU9qZuPkpYDs+ipQjzhoIJaY4HU2Uz4jMptqxSdzsPpC6PAKwuN\n"
+            + "+LBCR0B194YbRn6726vWwUUE05yskVN6gllGSCgZ/G8y98DhjQ==\n"
+            + "-----END CERTIFICATE-----&sslMode&password=testj&password=pwd2";
+    Configuration jdbc = Configuration.parse(url);
+    assertEquals("diego", jdbc.user());
+    assertEquals(true, jdbc.autocommit());
+    assertEquals(
+        "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDITCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQUFADBIMSMwIQYDVQQDExpHb29n\n"
+            + "bGUgQ2xvdWQgU1FMIFNlcnZlciBDQTEUMBIGA1UEChMLR29vZ2xlLCBJbmMxCzAJ\n"
+            + "BgNVBAYTAlVTMB4XDTE3MDQyNzEyMjcyNFoXDTE5MDQyNzEyMjgyNFowSDEjMCEG\n"
+            + "A1UEAxMaR29vZ2xlIENsb3VkIFNRTCBTZXJ2ZXIgQ0ExFDASBgNVBAoTC0dvb2ds\n"
+            + "ZSwgSW5jMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n"
+            + "ggEBANA6vS37//gvYOsEXKA9Cnlt/C1Ef/a5zJNahpVxx8HbJn6DF+pQbhHm3o4P\n"
+            + "TeZp1HoRg5TRiXOEkNTBmgSQbR2+otM2q2gmkn4XAh0+yXkNW3hr2IydJyg9C26v\n"
+            + "/OzFvuLcw9iDBvrn433pDa6vjYDU+wiQaVtr1ItzsoE/kgW2IkgFVQB+CrkpAmwm\n"
+            + "omwEze3QFUUznP0PHy3P7g7UVD9u5x3APY6kVt2dq8mnOiLZkyfHHR2j6+j0E73I\n"
+            + "k3HQv7D0yRIv3kuNpFgJbITVgDIq9ukWU2XinDHUjguCDH+yQAoQH7hOQlWUHIz8\n"
+            + "/TtfZjrlUQf2uLzOWCn5KxfEqTkCAwEAAaMWMBQwEgYDVR0TAQH/BAgwBgEB/wIB\n"
+            + "ADANBgkqhkiG9w0BAQUFAAOCAQEArYkBkUvMvteT4fN6lxUkzmp8R7clLPkA2HnJ\n"
+            + "7IUK3c5GJ0/blffxj/9Oe2g+etga15SIO73GNAnTxhxIJllKRmmh6SR+dwNMkAvE\n"
+            + "xp87/Y6cSeJp5d4HhZUvxpFjaUDsWIC8tpbriUJoqGIirprLVcsPgDjKyuvVOlbK\n"
+            + "aQf3fOoBPLspGWHgic8Iw1O4kRcStUGCSCwOtYcgMJEhVqTgX0sTX5BgatZhr8FY\n"
+            + "Mnoceo2vzzxgHJU9qZuPkpYDs+ipQjzhoIJaY4HU2Uz4jMptqxSdzsPpC6PAKwuN\n"
+            + "+LBCR0B194YbRn6726vWwUUE05yskVN6gllGSCgZ/G8y98DhjQ==\n"
+            + "-----END CERTIFICATE-----",
+        jdbc.serverSslCert());
+    assertEquals(SslMode.DISABLE, jdbc.sslMode());
+    assertEquals("pwd2", jdbc.password());
+  }
+
+  @Test
+  public void builder() throws SQLException {
+    Configuration conf =
+        new Configuration.Builder()
+            .addresses(
+                HostAddress.from("host1", 3305, true), HostAddress.from("host2", 3307, false))
+            .user("me")
+            .password("pwd")
+            .database("db")
+            .socketFactory("someSocketFactory")
+            .connectTimeout(22)
+            .restrictedAuth("mysql_native_password,client_ed25519")
+            .pipe("pipeName")
+            .localSocket("localSocket")
+            .tcpKeepAlive(false)
+            .uuidAsString(true)
+            .tcpAbortiveClose(true)
+            .localSocketAddress("localSocketAddress")
+            .socketTimeout(1000)
+            .allowMultiQueries(true)
+            .allowLocalInfile(false)
+            .useCompression(true)
+            .blankTableNameMeta(true)
+            .credentialType("ENV")
+            .sslMode("REQUIRED")
+            .enabledSslCipherSuites("myCipher,cipher2")
+            .sessionVariables("blabla")
+            .tinyInt1isBit(false)
+            .yearIsDateType(false)
+            .timezone("UTC")
+            .dumpQueriesOnException(true)
+            .prepStmtCacheSize(2)
+            .useAffectedRows(true)
+            .useServerPrepStmts(true)
+            .connectionAttributes("bla=bla")
+            .useBulkStmts(false)
+            .autocommit(false)
+            .includeInnodbStatusInDeadlockExceptions(true)
+            .includeThreadDumpInDeadlockExceptions(true)
+            .servicePrincipalName("SPN")
+            .defaultFetchSize(10)
+            .tlsSocketType("TLStype")
+            .maxQuerySizeToLog(100)
+            .retriesAllDown(10)
+            .galeraAllowedState("A,B")
+            .enabledSslProtocolSuites("TLSv1.2")
+            .transactionReplay(true)
+            .pool(true)
+            .poolName("myPool")
+            .maxPoolSize(16)
+            .minPoolSize(12)
+            .maxIdleTime(25000)
+            .transactionIsolation("REPEATABLE-READ")
+            .keyStore("/tmp")
+            .keyStorePassword("MyPWD")
+            .keyStoreType("JKS")
+            .geometryDefaultType("default")
+            .registerJmxPool(false)
+            .tcpKeepCount(50)
+            .tcpKeepIdle(10)
+            .tcpKeepInterval(50)
+            .poolValidMinDelay(260)
+            .useResetConnection(true)
+            .useReadAheadInput(true)
+            .cachePrepStmts(false)
+            .serverSslCert("mycertPath")
+            .serverRsaPublicKeyFile("RSAPath")
+            .allowPublicKeyRetrieval(true)
+            .createDatabaseIfNotExist(true)
+            .disablePipeline(true)
+            .maxAllowedPacket(8000)
+            .initSql("SET @@a='10'")
+            .build();
+    assertEquals(
+        "jdbc:mariadb://host1:3305,address=(host=host2)(port=3307)(type=replica)/db?user=me&password=***&timezone=UTC&autocommit=false&createDatabaseIfNotExist=true&transactionIsolation=REPEATABLE_READ&defaultFetchSize=10&maxQuerySizeToLog=100&maxAllowedPacket=8000&geometryDefaultType=default&restrictedAuth=mysql_native_password,client_ed25519&initSql=SET"
+            + " @@a='10'&socketFactory=someSocketFactory&connectTimeout=22&pipe=pipeName&localSocket=localSocket&uuidAsString=true&tcpKeepAlive=false&tcpKeepIdle=10&tcpKeepCount=50&tcpKeepInterval=50&tcpAbortiveClose=true&localSocketAddress=localSocketAddress&socketTimeout=1000&useReadAheadInput=true&tlsSocketType=TLStype&sslMode=TRUST&serverSslCert=mycertPath&keyStore=/tmp&keyStorePassword=MyPWD&keyStoreType=JKS&enabledSslCipherSuites=myCipher,cipher2&enabledSslProtocolSuites=TLSv1.2&allowMultiQueries=true&allowLocalInfile=false&useCompression=true&useAffectedRows=true&useBulkStmts=false&disablePipeline=true&cachePrepStmts=false&prepStmtCacheSize=2&useServerPrepStmts=true&credentialType=ENV&sessionVariables=blabla&connectionAttributes=bla=bla&servicePrincipalName=SPN&blankTableNameMeta=true&tinyInt1isBit=false&yearIsDateType=false&dumpQueriesOnException=true&includeInnodbStatusInDeadlockExceptions=true&includeThreadDumpInDeadlockExceptions=true&retriesAllDown=10&galeraAllowedState=A,B&transactionReplay=true&pool=true&poolName=myPool&maxPoolSize=16&minPoolSize=12&maxIdleTime=25000&registerJmxPool=false&poolValidMinDelay=260&useResetConnection=true&serverRsaPublicKeyFile=RSAPath&allowPublicKeyRetrieval=true",
+        conf.toString());
+  }
+
+  @Test
+  public void equal() throws SQLException {
+    Configuration conf = Configuration.parse("jdbc:mariadb://localhost/test");
+    assertEquals(conf, conf);
+    assertEquals(Configuration.parse("jdbc:mariadb://localhost/test"), conf);
+    assertNotEquals(null, conf);
+    assertNotEquals("", conf);
+    assertNotEquals(Configuration.parse("jdbc:mariadb://localhost/test2"), conf);
+  }
+
+  @Test
+  public void useMysqlMetadata() throws SQLException {
+    assertTrue(
+        new Configuration.Builder()
+            .database("DB")
+            .useMysqlMetadata(true)
+            .build()
+            .useMysqlMetadata());
+
+    assertFalse(
+        new Configuration.Builder()
+            .database("DB")
+            .useMysqlMetadata(false)
+            .build()
+            .useMysqlMetadata());
+
+    assertFalse(
+        new Configuration.Builder()
+            .database("DB")
+            .useMysqlMetadata(null)
+            .build()
+            .useMysqlMetadata());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/ParameterListTest.java b/src/test/java/org/mariadb/jdbc/unit/util/ParameterListTest.java
new file mode 100644
index 0000000..a2aa2f9
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/ParameterListTest.java
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.codec.Parameter;
+import org.mariadb.jdbc.plugin.codec.StringCodec;
+import org.mariadb.jdbc.util.ParameterList;
+
+public class ParameterListTest {
+
+  @Test
+  public void sizeLimit() {
+    ParameterList p = new ParameterList();
+    p.set(2, new Parameter<>(StringCodec.INSTANCE, "test2"));
+    assertNull(p.get(1));
+    assertNotNull(p.get(2));
+    assertThrows(ArrayIndexOutOfBoundsException.class, () -> p.get(3));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/SecurityTest.java b/src/test/java/org/mariadb/jdbc/unit/util/SecurityTest.java
new file mode 100644
index 0000000..0495834
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/SecurityTest.java
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.Security;
+
+@SuppressWarnings("ConstantConditions")
+public class SecurityTest {
+
+  @Test
+  public void parser() {
+    assertEquals(
+        "wait_timeout=5,some='bla;'", Security.parseSessionVariables("wait_timeout=5,some='bla;'"));
+    assertEquals(
+        "wait_timeout=5,some='bla\"\\n=;'",
+        Security.parseSessionVariables("wait_timeout=5;some='bla\"\\n=;'"));
+    assertEquals(
+        "wait_timeout=5,some=\"bla;'\"",
+        Security.parseSessionVariables("wait_timeout=5;some=\"bla;'\""));
+    assertEquals("wait_timeout", Security.parseSessionVariables("wait_timeout"));
+    assertEquals("wait_timeout=", Security.parseSessionVariables("wait_timeout="));
+    assertEquals("wait_timeout=1,t=", Security.parseSessionVariables("wait_timeout=1,t="));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/VersionFactoryTest.java b/src/test/java/org/mariadb/jdbc/unit/util/VersionFactoryTest.java
new file mode 100644
index 0000000..38e6352
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/VersionFactoryTest.java
@@ -0,0 +1,17 @@
+package org.mariadb.jdbc.unit.util;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.Version;
+import org.mariadb.jdbc.util.VersionFactory;
+
+class VersionFactoryTest {
+
+  @Test
+  public void testGetInstance() {
+    Version actual = VersionFactory.getInstance();
+
+    assertNotNull(actual);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/VersionTest.java b/src/test/java/org/mariadb/jdbc/unit/util/VersionTest.java
new file mode 100644
index 0000000..8ff3816
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/VersionTest.java
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.Version;
+
+@SuppressWarnings("ConstantConditions")
+public class VersionTest {
+
+  @Test
+  public void testValue() {
+    Version v = new Version("3.0.0-alpha-SNAPSHOT");
+    assertEquals(3, v.getMajorVersion());
+    assertEquals(0, v.getMinorVersion());
+    assertEquals(0, v.getPatchVersion());
+    assertEquals("-alpha-SNAPSHOT", v.getQualifier());
+
+    v = new Version("3.0.0=alpha-SNAPSHOT");
+    assertEquals(3, v.getMajorVersion());
+    assertEquals(0, v.getMinorVersion());
+    assertEquals(0, v.getPatchVersion());
+    assertEquals("=alpha-SNAPSHOT", v.getQualifier());
+
+    v = new Version("3.0.1");
+    assertEquals(3, v.getMajorVersion());
+    assertEquals(0, v.getMinorVersion());
+    assertEquals(1, v.getPatchVersion());
+    assertEquals("", v.getQualifier());
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/constant/HaModeTest.java b/src/test/java/org/mariadb/jdbc/unit/util/constant/HaModeTest.java
new file mode 100644
index 0000000..d72c79c
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/constant/HaModeTest.java
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util.constant;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.HostAddress;
+import org.mariadb.jdbc.client.impl.ConnectionHelper;
+import org.mariadb.jdbc.client.socket.impl.SocketUtility;
+import org.mariadb.jdbc.export.HaMode;
+import org.mariadb.jdbc.plugin.authentication.AuthenticationPluginLoader;
+import org.mariadb.jdbc.plugin.credential.CredentialPluginLoader;
+import org.mariadb.jdbc.plugin.tls.TlsSocketPluginLoader;
+import org.mariadb.jdbc.pool.Pools;
+import org.mariadb.jdbc.util.CharsetEncodingLength;
+import org.mariadb.jdbc.util.NativeSql;
+import org.mariadb.jdbc.util.Security;
+import org.mariadb.jdbc.util.VersionFactory;
+import org.mariadb.jdbc.util.constants.*;
+import org.mariadb.jdbc.util.log.LoggerHelper;
+import org.mariadb.jdbc.util.log.Loggers;
+import org.mariadb.jdbc.util.options.OptionAliases;
+
+public class HaModeTest {
+  @Test
+  public void instantiateStaticOnlyClass() {
+    new Capabilities();
+    new ColumnFlags();
+    new ConnectionState();
+    new ServerStatus();
+    new StateChange();
+    new CharsetEncodingLength();
+    new NativeSql();
+    new Security();
+    new OptionAliases();
+    new CredentialPluginLoader();
+    new AuthenticationPluginLoader();
+    new TlsSocketPluginLoader();
+    new LoggerHelper();
+    new ConnectionHelper();
+    new Pools();
+    new Loggers();
+    new VersionFactory();
+    new SocketUtility();
+  }
+
+  @Test
+  public void replicationEndOfBlacklistTest() {
+    HostAddress host1 = HostAddress.from("1", 3306, true);
+    HostAddress host2 = HostAddress.from("2", 3306, false);
+    HostAddress host3 = HostAddress.from("3", 3306, false);
+
+    List<HostAddress> available = new ArrayList<>();
+    available.add(host1);
+    available.add(host2);
+    available.add(host3);
+
+    ConcurrentMap<HostAddress, Long> denyList = new ConcurrentHashMap<>();
+    denyList.putIfAbsent(host1, System.currentTimeMillis() - 10);
+
+    Optional<HostAddress> res = HaMode.REPLICATION.getAvailableHost(available, denyList, true);
+    Assertions.assertTrue(res.isPresent());
+    Assertions.assertEquals(host1, res.get());
+
+    int replica1 = 0;
+    int replica2 = 0;
+    for (int i = 0; i < 1000; i++) {
+      res = HaMode.REPLICATION.getAvailableHost(available, denyList, false);
+      Assertions.assertTrue(res.isPresent());
+      if (host2.equals(res.get())) replica1++;
+      if (host3.equals(res.get())) replica2++;
+    }
+    assertTrue(replica1 > 350 && replica2 > 350, "bad distribution :" + replica1 + "/" + replica2);
+
+    replica1 = 0;
+    replica2 = 0;
+    denyList.putIfAbsent(host2, System.currentTimeMillis() - 10);
+    for (int i = 0; i < 1000; i++) {
+      res = HaMode.REPLICATION.getAvailableHost(available, denyList, false);
+      Assertions.assertTrue(res.isPresent());
+      if (host2.equals(res.get())) replica1++;
+      if (host3.equals(res.get())) replica2++;
+    }
+    assertTrue(replica1 > 350 && replica2 > 350, "bad distribution :" + replica1 + "/" + replica2);
+
+    for (int i = 0; i < 1000; i++) {
+      denyList.putIfAbsent(host2, System.currentTimeMillis() + 1000);
+      res = HaMode.REPLICATION.getAvailableHost(available, denyList, false);
+      Assertions.assertTrue(res.isPresent());
+      Assertions.assertEquals(host3, res.get());
+    }
+  }
+
+  @Test
+  public void loadBalanceTest() throws InterruptedException {
+    HostAddress host1 = HostAddress.from("1", 3306, true);
+    HostAddress host2 = HostAddress.from("2", 3306, true);
+    HostAddress host3 = HostAddress.from("3", 3306, true);
+    HostAddress host4 = HostAddress.from("4", 3306, false);
+    HostAddress host5 = HostAddress.from("5", 3306, false);
+    HostAddress host6 = HostAddress.from("6", 3306, false);
+
+    List<HostAddress> available = new ArrayList<>();
+    available.add(host1);
+    available.add(host2);
+    available.add(host3);
+    available.add(host4);
+    available.add(host5);
+    available.add(host6);
+
+    ConcurrentMap<HostAddress, Long> denyList = new ConcurrentHashMap<>();
+    Map<HostAddress, Integer> res = loopPercReturn(available, denyList, true);
+    Assertions.assertEquals(334, res.get(host1));
+    Assertions.assertEquals(333, res.get(host2));
+    Assertions.assertEquals(333, res.get(host3));
+
+    denyList.putIfAbsent(host1, System.currentTimeMillis() + 1000000);
+
+    res = loopPercReturn(available, denyList, true);
+    Assertions.assertEquals(null, res.get(host1));
+    Assertions.assertEquals(500, res.get(host2));
+    Assertions.assertEquals(500, res.get(host3));
+
+    denyList.clear();
+    denyList.putIfAbsent(host1, System.currentTimeMillis() - 1000000);
+
+    res = loopPercReturn(available, denyList, true);
+    Assertions.assertEquals(334, res.get(host1));
+    Assertions.assertEquals(333, res.get(host2));
+    Assertions.assertEquals(333, res.get(host3));
+
+    res = loopPercReturn(available, denyList, false);
+    Assertions.assertEquals(334, res.get(host4));
+    Assertions.assertEquals(333, res.get(host5));
+    Assertions.assertEquals(333, res.get(host6));
+  }
+
+  @Test
+  public void noneTest() {
+    HostAddress host1 = HostAddress.from("1", 3306, true);
+
+    List<HostAddress> available = new ArrayList<>();
+    available.add(host1);
+
+    ConcurrentMap<HostAddress, Long> denyList = new ConcurrentHashMap<>();
+
+    Optional<HostAddress> res = HaMode.NONE.getAvailableHost(available, denyList, true);
+    Assertions.assertTrue(res.isPresent());
+    Assertions.assertEquals(host1, res.get());
+
+    res = HaMode.NONE.getAvailableHost(new ArrayList<>(), denyList, true);
+    Assertions.assertFalse(res.isPresent());
+  }
+
+  private Map<HostAddress, Integer> loopPercReturn(
+      List<HostAddress> available, ConcurrentMap<HostAddress, Long> denyList, boolean primary) {
+    Map<HostAddress, Integer> resMap = new HashMap<>();
+    for (int i = 0; i < 1000; i++) {
+      Optional<HostAddress> res = HaMode.LOADBALANCE.getAvailableHost(available, denyList, primary);
+      if (res.isPresent()) {
+        if (resMap.containsKey(res.get())) {
+          resMap.put(res.get(), resMap.get(res.get()) + 1);
+        } else {
+          resMap.put(res.get(), 1);
+        }
+      }
+    }
+    return resMap;
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/log/ConsoleLoggerTest.java b/src/test/java/org/mariadb/jdbc/unit/util/log/ConsoleLoggerTest.java
new file mode 100644
index 0000000..a2e2870
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/log/ConsoleLoggerTest.java
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util.log;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.sql.SQLException;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.log.ConsoleLogger;
+
+public class ConsoleLoggerTest {
+
+  @Test
+  public void logger() throws IOException {
+    logger(true);
+    logger(false);
+  }
+
+  public void logger(boolean logDebug) throws IOException {
+    try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+      try (ByteArrayOutputStream err = new ByteArrayOutputStream()) {
+
+        ConsoleLogger logger =
+            new ConsoleLogger("test", new PrintStream(out), new PrintStream(err), logDebug);
+
+        assertEquals("test", logger.getName());
+        assertTrue(logger.isErrorEnabled());
+        logger.error("error msg");
+        logger.error("error msg3 {} {}", 1, "t");
+        logger.error("error msg4 {}", (String) null);
+        logger.error(null, (String) null);
+        logger.error("error msg2", new SQLException("test"));
+
+        assertTrue(logger.isInfoEnabled());
+        logger.info("info msg");
+        logger.info("info msg3 {} {}", 1, "t");
+        logger.info("info msg2", new SQLException("test"));
+
+        assertTrue(logger.isWarnEnabled());
+        logger.warn("warn msg");
+        logger.warn("warn msg3 {} {}", 1, "t");
+        logger.warn("warn msg2", new SQLException("test"));
+
+        assertEquals(logDebug, logger.isDebugEnabled());
+        logger.debug("debug msg");
+        logger.debug("debug msg3 {} {}", 1, "t");
+        logger.debug("debug msg2", new SQLException("test"));
+
+        assertEquals(logDebug, logger.isTraceEnabled());
+        logger.trace("trace msg");
+        logger.trace("trace msg3 {} {}", 1, "t");
+        logger.trace("trace msg2", new SQLException("test"));
+
+        String errSt = err.toString();
+        String outSt = out.toString();
+
+        assertTrue(
+            errSt.contains(
+                "[ERROR] (main) error msg\n"
+                    + "[ERROR] (main) error msg3 1 t\n"
+                    + "[ERROR] (main) error msg4 null\n"
+                    + "[ERROR] (main) null\n"
+                    + "[ERROR] (main) error msg2 - java.sql.SQLException: test"));
+        assertTrue(
+            errSt.contains(
+                "[ WARN] (main) warn msg\n"
+                    + "[ WARN] (main) warn msg3 1 t\n"
+                    + "[ WARN] (main) warn msg2 - java.sql.SQLException: test"));
+        assertTrue(
+            outSt.contains(
+                "[ INFO] (main) info msg\n"
+                    + "[ INFO] (main) info msg3 1 t\n"
+                    + "[ INFO] (main) info msg2 - java.sql.SQLException: test"));
+        if (logDebug) {
+          assertTrue(
+              outSt.contains(
+                  "[DEBUG] (main) debug msg\n"
+                      + "[DEBUG] (main) debug msg3 1 t\n"
+                      + "[DEBUG] (main) debug msg2 - java.sql.SQLException: test"));
+          assertTrue(
+              outSt.contains(
+                  "[TRACE] (main) trace msg\n"
+                      + "[TRACE] (main) trace msg3 1 t\n"
+                      + "[TRACE] (main) trace msg2 - java.sql.SQLException: test"));
+        } else {
+          assertFalse(outSt.contains("[DEBUG]"));
+          assertFalse(outSt.contains("[TRACE]"));
+        }
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/log/JdkLoggerTest.java b/src/test/java/org/mariadb/jdbc/unit/util/log/JdkLoggerTest.java
new file mode 100644
index 0000000..9bbaa4b
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/log/JdkLoggerTest.java
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util.log;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.sql.SQLException;
+import java.time.ZonedDateTime;
+import java.util.logging.*;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.log.JdkLogger;
+
+public class JdkLoggerTest {
+  final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+  public class BufHandler extends StreamHandler {
+    public BufHandler() {
+      super(out, new MySimpleFormatter());
+    }
+
+    public void publish(LogRecord record) {
+      super.publish(record);
+      this.flush();
+    }
+
+    public void close() {
+      this.flush();
+    }
+  }
+
+  public static class MySimpleFormatter extends Formatter {
+
+    public MySimpleFormatter() {}
+
+    public String format(LogRecord record) {
+      ZonedDateTime zdt = ZonedDateTime.now();
+      String source;
+      if (record.getSourceClassName() != null) {
+        source = record.getSourceClassName();
+        if (record.getSourceMethodName() != null) {
+          source = source + " " + record.getSourceMethodName();
+        }
+      } else {
+        source = record.getLoggerName();
+      }
+
+      String message = this.formatMessage(record);
+      String throwable = "";
+      if (record.getThrown() != null) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        pw.println();
+        record.getThrown().printStackTrace(pw);
+        pw.close();
+        throwable = sw.toString();
+      }
+
+      return String.format(
+          "[%4$-7s] %5$s %n",
+          zdt, source, record.getLoggerName(), Level.FINEST, message, throwable);
+    }
+  }
+
+  @Test
+  public void logger() {
+
+    java.util.logging.Logger log = Logger.getLogger("logger");
+    log.addHandler(new BufHandler());
+    log.setLevel(Level.FINEST);
+    JdkLogger logger = new JdkLogger(log);
+
+    assertEquals("logger", logger.getName());
+    assertTrue(logger.isErrorEnabled());
+    logger.error("error msg");
+    logger.error("error msg3 {} {}", 1, "t");
+    logger.error("error msg4 {}", (String) null);
+    logger.error(null, (String) null);
+    logger.error("error msg2", new SQLException("test"));
+
+    assertTrue(logger.isInfoEnabled());
+    logger.info("info msg");
+    logger.info("info msg3 {} {}", 1, "t");
+    logger.info("info msg2", new SQLException("test"));
+
+    assertTrue(logger.isWarnEnabled());
+    logger.warn("warn msg");
+    logger.warn("warn msg3 {} {}", 1, "t");
+    logger.warn("warn msg2", new SQLException("test"));
+
+    assertTrue(logger.isDebugEnabled());
+    logger.debug("debug msg");
+    logger.debug("debug msg3 {} {}", 1, "t");
+    logger.debug("debug msg2", new SQLException("test"));
+
+    assertTrue(logger.isTraceEnabled());
+    logger.trace("trace msg");
+    logger.trace("trace msg3 {} {}", 1, "t");
+    logger.trace("trace msg3 {} {}", (String) null);
+    logger.trace("trace msg2", new SQLException("test"));
+
+    String outSt = out.toString();
+    String expected =
+        "[FINEST ] error msg \n"
+            + "[FINEST ] error msg3 1 t \n"
+            + "[FINEST ] error msg4 null \n"
+            + "[FINEST ] null \n"
+            + "[FINEST ] error msg2 \n"
+            + "[FINEST ] info msg \n"
+            + "[FINEST ] info msg3 1 t \n"
+            + "[FINEST ] info msg2 \n"
+            + "[FINEST ] warn msg \n"
+            + "[FINEST ] warn msg3 1 t \n"
+            + "[FINEST ] warn msg2 ";
+    assertTrue(outSt.contains(expected) || outSt.replace("\r\n", "\n").contains(expected));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/log/LoggerFactoryTest.java b/src/test/java/org/mariadb/jdbc/unit/util/log/LoggerFactoryTest.java
new file mode 100644
index 0000000..d359fbf
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/log/LoggerFactoryTest.java
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util.log;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.log.ConsoleLogger;
+import org.mariadb.jdbc.util.log.JdkLogger;
+import org.mariadb.jdbc.util.log.Loggers;
+import org.mariadb.jdbc.util.log.Slf4JLogger;
+
+public class LoggerFactoryTest {
+
+  @AfterAll
+  public static void drop() {
+    System.clearProperty(Loggers.TEST_ENABLE_SLF4J);
+    System.clearProperty(Loggers.FALLBACK_PROPERTY);
+    System.clearProperty(Loggers.CONSOLE_DEBUG_PROPERTY);
+    Loggers.init();
+  }
+
+  @Test
+  public void defaultSlf4j() {
+    System.clearProperty(Loggers.TEST_ENABLE_SLF4J);
+    System.clearProperty(Loggers.FALLBACK_PROPERTY);
+    Loggers.init();
+    assertTrue(Loggers.getLogger("test") instanceof Slf4JLogger);
+  }
+
+  @Test
+  public void commonLogger() {
+    System.setProperty(Loggers.TEST_ENABLE_SLF4J, "false");
+    System.setProperty(Loggers.FALLBACK_PROPERTY, "JDK");
+    Loggers.init();
+    assertTrue(Loggers.getLogger("test") instanceof JdkLogger);
+  }
+
+  @Test
+  public void consoleLogger() {
+    System.setProperty(Loggers.TEST_ENABLE_SLF4J, "false");
+    System.clearProperty(Loggers.FALLBACK_PROPERTY);
+    Loggers.init();
+    assertTrue(Loggers.getLogger("test") instanceof ConsoleLogger);
+    System.setProperty(Loggers.CONSOLE_DEBUG_PROPERTY, "true");
+    Loggers.init();
+    assertTrue(Loggers.getLogger("test") instanceof ConsoleLogger);
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/log/LoggerHelperTest.java b/src/test/java/org/mariadb/jdbc/unit/util/log/LoggerHelperTest.java
new file mode 100644
index 0000000..af94bfa
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/log/LoggerHelperTest.java
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util.log;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.log.LoggerHelper;
+
+class LoggerHelperTest {
+
+  @Test
+  void hex() {
+    byte[] bb =
+        new byte[] {
+          0x4A, 0x00, 0x00, 0x00, 0x03, 0x53, 0x45, 0x4C, 0x45,
+          0x43, 0x54, 0x20, 0x40, 0x40, 0x6D, 0x61, 0x78, 0x5F,
+          0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x5F, 0x70,
+          0x61, 0x63, 0x6B, 0x65, 0x74, 0x20, 0x2C, 0x20, 0x40,
+          0x40, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x5F, 0x74,
+          0x69, 0x6D, 0x65, 0x5F, 0x7A, 0x6F, 0x6E, 0x65, 0x2C,
+          0x20, 0x40, 0x40, 0x74, 0x69, 0x6D, 0x65, 0x5F, 0x7A,
+          0x6F, 0x6E, 0x65, 0x2C, 0x20, 0x40, 0x40, 0x73, 0x71,
+          0x6C, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x64, 0x65
+        };
+
+    Assertions.assertEquals("", LoggerHelper.hex(null, 0, 2));
+    Assertions.assertEquals("", LoggerHelper.hex(new byte[0], 0, 2));
+
+    Assertions.assertEquals(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| 4A 00 00 00 03 53 45 4C  45 43 54 20 40 40 6D 61 | J....SELECT @@ma |\n"
+            + "|000010| 78 5F 61 6C 6C 6F 77 65  64 5F 70 61 63 6B 65 74 | x_allowed_packet |\n"
+            + "|000020| 20 2C 20 40 40 73 79 73  74 65 6D 5F 74 69 6D 65 |  , @@system_time |\n"
+            + "|000030| 5F 7A 6F 6E 65 2C 20 40  40 74 69 6D 65 5F 7A 6F | _zone, @@time_zo |\n"
+            + "|000040| 6E 65 2C 20 40 40 73 71  6C 5F 6D 6F 64 65       | ne, @@sql_mode   |\n"
+            + "+------+--------------------------------------------------+------------------+\n",
+        LoggerHelper.hex(bb, 0, bb.length - 2));
+
+    Assertions.assertEquals(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| 4A 00 00 00 03 53 45 4C  45 43 54 20 40 40 6D 61 | J....SELECT @@ma |\n"
+            + "+------+-------------------truncated----------------------+------------------+\n",
+        LoggerHelper.hex(bb, 0, bb.length - 2, 16));
+
+    assertEquals(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| 4A 00 00 00 03 53 45 4C  45 43 54 20 40 40 6D 61 | J....SELECT @@ma |\n"
+            + "|000010| 78 5F 61 6C 6C 6F 77 65  64 5F 70 61 63 6B 65 74 | x_allowed_packet |\n"
+            + "|000020| 20 2C 20 40 40 73 79 73  74 65 6D 5F 74 69 6D 65 |  , @@system_time |\n"
+            + "|000030| 5F 7A 6F 6E 65 2C 20 40  40 74 69 6D 65 5F 7A 6F | _zone, @@time_zo |\n"
+            + "|000040| 6E 65 2C 20 40 40 73 71  6C 5F 6D 6F 64 65 64 65 | ne, @@sql_modede |\n"
+            + "+------+--------------------------------------------------+------------------+\n",
+        LoggerHelper.hex(bb, 0, bb.length));
+
+    assertEquals(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| 00 00 00 03 53 45 4C 45  43 54 20 40 40 6D 61 78 | ....SELECT @@max |\n"
+            + "+------+--------------------------------------------------+------------------+\n",
+        LoggerHelper.hex(bb, 1, 16));
+
+    assertEquals(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| 00 00 00 03 53 45 4C 45  43 54 20 40 40 6D 61 78 | ....SELECT @@max |\n"
+            + "|000010| 5F                                               | _                |\n"
+            + "+------+--------------------------------------------------+------------------+\n",
+        LoggerHelper.hex(bb, 1, 17));
+    byte[] header = new byte[] {1, 2, 3, 4};
+
+    assertEquals(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| 01 02 03 04 00 00 00 03  53 45 4C 45 43 54 20 40 | ........SELECT @ |\n"
+            + "|000010| 40 6D 61 78                                      | @max             |\n"
+            + "+------+--------------------------------------------------+------------------+\n",
+        LoggerHelper.hex(header, bb, 1, 16, Integer.MAX_VALUE));
+    assertEquals(
+        "       +--------------------------------------------------+\n"
+            + "       |  0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f |\n"
+            + "+------+--------------------------------------------------+------------------+\n"
+            + "|000000| 01 02 03 04 00 00 00 03  53 45 4C 45 43 54 20 40 | ........SELECT @ |\n"
+            + "|000010| 40                                               | @                |\n"
+            + "+------+-------------------truncated----------------------+------------------+\n",
+        LoggerHelper.hex(header, bb, 1, 16, 17));
+  }
+}
diff --git a/src/test/java/org/mariadb/jdbc/unit/util/log/LoggersTest.java b/src/test/java/org/mariadb/jdbc/unit/util/log/LoggersTest.java
new file mode 100644
index 0000000..42cb7b5
--- /dev/null
+++ b/src/test/java/org/mariadb/jdbc/unit/util/log/LoggersTest.java
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (c) 2012-2014 Monty Program Ab
+// Copyright (c) 2015-2021 MariaDB Corporation Ab
+
+package org.mariadb.jdbc.unit.util.log;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.FileAppender;
+import java.io.*;
+import java.sql.SQLException;
+import org.junit.jupiter.api.Test;
+import org.mariadb.jdbc.util.log.Logger;
+import org.mariadb.jdbc.util.log.Loggers;
+import org.slf4j.LoggerFactory;
+
+public class LoggersTest {
+
+  @Test
+  public void Slf4JLogger() throws IOException {
+    ch.qos.logback.classic.Logger root =
+        (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(this.getClass());
+    root.setLevel(Level.TRACE);
+
+    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+    PatternLayoutEncoder ple = new PatternLayoutEncoder();
+    ple.setPattern("%level %logger{10} [%file] %msg%n");
+    ple.setContext(lc);
+    ple.start();
+
+    File tempfile = File.createTempFile("debug-", ".log");
+    FileAppender<ILoggingEvent> fileAppender = new FileAppender<>();
+    fileAppender.setFile(tempfile.getCanonicalPath());
+    fileAppender.setEncoder(ple);
+    fileAppender.setContext(lc);
+    fileAppender.start();
+
+    root.addAppender(fileAppender);
+    Logger logger = Loggers.getLogger(LoggersTest.class);
+    assertTrue(logger.isErrorEnabled());
+    assertTrue(logger.isWarnEnabled());
+    assertTrue(logger.isInfoEnabled());
+    assertTrue(logger.isDebugEnabled());
+    assertTrue(logger.isTraceEnabled());
+    assertEquals("org.mariadb.jdbc.unit.util.log.LoggersTest", logger.getName());
+    Logger logger2 = Loggers.getLogger("bla");
+    assertEquals("bla", logger2.getName());
+
+    logger.error("Test err1");
+    logger.error("Test err2", new SQLException("test exception"));
+    logger.error("Test err3 {}", "param");
+
+    logger.warn("Test warn 1");
+    logger.warn("Test warn 2", new SQLException("test exception"));
+    logger.warn("Test warn 3 {}", "param");
+
+    logger.info("Test info 1");
+    logger.info("Test info 2", new SQLException("test exception"));
+    logger.info("Test info 3 {}", "param");
+
+    logger.debug("Test debug 1");
+    logger.debug("Test debug 2", new SQLException("test exception"));
+    logger.debug("Test debug 3 {}", "param");
+
+    logger.trace("Test trace 1");
+    logger.trace("Test trace 2", new SQLException("test exception"));
+    logger.trace("Test trace 3 {}", "param");
+
+    BufferedReader reader = new BufferedReader(new FileReader(tempfile.getCanonicalPath()));
+    assertEquals("ERROR o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test err1", reader.readLine());
+    assertEquals("ERROR o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test err2", reader.readLine());
+    assertEquals("java.sql.SQLException: test exception", reader.readLine());
+    String line;
+    do {
+      line = reader.readLine();
+    } while (line != null && line.startsWith("\tat "));
+
+    assertEquals("ERROR o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test err3 param", line);
+    assertEquals("WARN o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test warn 1", reader.readLine());
+    assertEquals("WARN o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test warn 2", reader.readLine());
+    assertEquals("java.sql.SQLException: test exception", reader.readLine());
+
+    do {
+      line = reader.readLine();
+    } while (line != null && line.startsWith("\tat "));
+
+    assertEquals("WARN o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test warn 3 param", line);
+    assertEquals("INFO o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test info 1", reader.readLine());
+    assertEquals("INFO o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test info 2", reader.readLine());
+    assertEquals("java.sql.SQLException: test exception", reader.readLine());
+
+    do {
+      line = reader.readLine();
+    } while (line != null && line.startsWith("\tat "));
+
+    assertEquals("INFO o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test info 3 param", line);
+    assertEquals(
+        "DEBUG o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test debug 1", reader.readLine());
+    assertEquals(
+        "DEBUG o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test debug 2", reader.readLine());
+    assertEquals("java.sql.SQLException: test exception", reader.readLine());
+
+    do {
+      line = reader.readLine();
+    } while (line != null && line.startsWith("\tat "));
+
+    assertEquals("DEBUG o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test debug 3 param", line);
+    assertEquals(
+        "TRACE o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test trace 1", reader.readLine());
+    assertEquals(
+        "TRACE o.m.j.u.u.l.LoggersTest [Slf4JLogger.java] Test trace 2", reader.readLine());
+    assertEquals("java.sql.SQLException: test exception", reader.readLine());
+
+    reader.close();
+  }
+}
diff --git a/src/test/resources/META-INF/services/org.mariadb.jdbc.plugin.CredentialPlugin b/src/test/resources/META-INF/services/org.mariadb.jdbc.plugin.CredentialPlugin
new file mode 100644
index 0000000..6311e36
--- /dev/null
+++ b/src/test/resources/META-INF/services/org.mariadb.jdbc.plugin.CredentialPlugin
@@ -0,0 +1,4 @@
+org.mariadb.jdbc.plugin.credential.aws.AwsIamCredentialPlugin
+org.mariadb.jdbc.plugin.credential.env.EnvCredentialPlugin
+org.mariadb.jdbc.plugin.credential.system.PropertiesCredentialPlugin
+org.mariadb.jdbc.integration.util.Env2CredentialPlugin
diff --git a/src/test/resources/conf.properties b/src/test/resources/conf.properties
new file mode 100644
index 0000000..59ad289
--- /dev/null
+++ b/src/test/resources/conf.properties
@@ -0,0 +1,7 @@
+DB_HOST=localhost
+DB_PORT=3306
+DB_DATABASE=testj
+DB_USER=root
+DB_PASSWORD=
+DB_OTHER=
+
diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..5587c71
--- /dev/null
+++ b/src/test/resources/logback-test.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+    <layout class="ch.qos.logback.classic.PatternLayout">
+      <Pattern>
+        %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
+      </Pattern>
+    </layout>
+  </appender>
+
+<!--  <logger name="org.mariadb.jdbc" level="trace" additivity="false">-->
+<!--    <appender-ref ref="CONSOLE"/>-->
+<!--  </logger>-->
+
+  <root level="error">
+    <appender-ref ref="CONSOLE"/>
+  </root>
+
+</configuration>
diff --git a/src/test/resources/testclient-keystore.p12 b/src/test/resources/testclient-keystore.p12
new file mode 100644
index 0000000..88544e3
--- /dev/null
+++ b/src/test/resources/testclient-keystore.p12
Binary files differ
