Skip to content

Commit 27edc7b

Browse files
svats0001jchrys
authored andcommitted
MariaDb extended type info changes
1 parent b9f0e83 commit 27edc7b

File tree

5 files changed

+74
-27
lines changed

5 files changed

+74
-27
lines changed

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/Capability.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public final class Capability {
169169
// private static final long MARIADB_CLIENT_PROGRESS = 1L << 32;
170170
// private static final long MARIADB_CLIENT_COM_MULTI = 1L << 33;
171171
// private static final long MARIADB_CLIENT_STMT_BULK_OPERATIONS = 1L << 34;
172-
172+
173173
/**
174174
* Receive extended column type information from MariaDB to find out more specific details about column type.
175175
*/
@@ -181,11 +181,22 @@ public final class Capability {
181181
TRANSACTIONS | SECURE_SALT | MULTI_STATEMENTS | MULTI_RESULTS | PS_MULTI_RESULTS |
182182
PLUGIN_AUTH | CONNECT_ATTRS | VAR_INT_SIZED_AUTH | SESSION_TRACK | DEPRECATE_EOF | ZSTD_COMPRESS;
183183

184+
private static final long ALL_SUPPORTED_MARIADB = FOUND_ROWS | LONG_FLAG | CONNECT_WITH_DB |
185+
NO_SCHEMA | COMPRESS | LOCAL_FILES | IGNORE_SPACE | PROTOCOL_41 | INTERACTIVE | SSL |
186+
TRANSACTIONS | SECURE_SALT | MULTI_STATEMENTS | MULTI_RESULTS | PS_MULTI_RESULTS | PLUGIN_AUTH |
187+
CONNECT_ATTRS | VAR_INT_SIZED_AUTH | SESSION_TRACK | DEPRECATE_EOF | ZSTD_COMPRESS |
188+
MARIADB_CLIENT_EXTENDED_TYPE_INFO;
189+
184190
/**
185191
* The default capabilities for a MySQL connection. It contains all client supported capabilities.
186192
*/
187193
public static final Capability DEFAULT = new Capability(ALL_SUPPORTED);
188194

195+
/**
196+
* The default capabilities for a MariaDB connection. It contains all client supported capabilities.
197+
*/
198+
public static final Capability DEFAULT_MARIADB = new Capability(ALL_SUPPORTED_MARIADB);
199+
189200
private final long bitmap;
190201

191202
/**
@@ -313,14 +324,14 @@ public boolean isZlibCompression() {
313324
public boolean isZstdCompression() {
314325
return (bitmap & ZSTD_COMPRESS) != 0;
315326
}
316-
327+
317328
/**
318329
* Checks if MariaDB extended type info enabled.
319-
*
330+
*
320331
* @return if MariaDB extended type info enabled.
321332
*/
322333
public boolean isExtendedTypeInfo() {
323-
return (bitmap & MARIADB_CLIENT_EXTENDED_TYPE_INFO) != 0;
334+
return (bitmap & MARIADB_CLIENT_EXTENDED_TYPE_INFO) != 0;
324335
}
325336

326337
/**

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/MySqlTypeMetadata.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ final class MySqlTypeMetadata implements MySqlNativeTypeMetadata {
6868
* collationId > 0 when protocol version == 4.1, 0 otherwise.
6969
*/
7070
private final int collationId;
71-
71+
7272
/**
7373
* The MariaDB extended type info field that provides more specific details about column type.
7474
*/
@@ -116,10 +116,10 @@ public boolean isEnum() {
116116
public boolean isSet() {
117117
return (definitions & SET) != 0;
118118
}
119-
119+
120120
@Override
121121
public boolean isMariaDbJson() {
122-
return extendedTypeInfo.equals("json");
122+
return (extendedTypeInfo == null ? false : extendedTypeInfo.equals("json"));
123123
}
124124

125125
@Override
@@ -133,22 +133,23 @@ public boolean equals(Object o) {
133133

134134
MySqlTypeMetadata that = (MySqlTypeMetadata) o;
135135

136-
return typeId == that.typeId && definitions == that.definitions && collationId == that.collationId &&
137-
Objects.equals(extendedTypeInfo, that.extendedTypeInfo);
136+
return typeId == that.typeId && definitions == that.definitions && collationId == that.collationId &&
137+
Objects.equals(extendedTypeInfo, that.extendedTypeInfo);
138138
}
139139

140140
@Override
141141
public int hashCode() {
142142
int result = 31 * typeId + (int) definitions;
143-
return 31 * result + collationId + extendedTypeInfo.hashCode();
143+
result = 31 * result + collationId;
144+
return 31 * result + (extendedTypeInfo == null ? 0 : extendedTypeInfo.hashCode());
144145
}
145146

146147
@Override
147148
public String toString() {
148149
return "MySqlTypeMetadata{typeId=" + typeId +
149150
", definitions=0x" + Integer.toHexString(definitions) +
150-
", collationId=" + collationId +
151-
", extendedTypeInfo=" + extendedTypeInfo +
152-
'}';
151+
", collationId=" + collationId +
152+
", extendedTypeInfo='" + extendedTypeInfo +
153+
"'}";
153154
}
154155
}

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/api/MySqlNativeTypeMetadata.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ public interface MySqlNativeTypeMetadata {
7171
* @return if value is a set
7272
*/
7373
boolean isSet();
74-
74+
7575
/**
7676
* Checks if value is JSON for MariaDb.
77-
*
77+
*
7878
* @return if value is a JSON for MariaDb
7979
*/
8080
boolean isMariaDbJson();

r2dbc-mysql/src/main/java/io/asyncer/r2dbc/mysql/message/server/DefinitionMetadataMessage.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public final class DefinitionMetadataMessage implements ServerMessage {
4545

4646
@Nullable
4747
private final String originColumn;
48-
48+
4949
@Nullable
5050
private final String extendedTypeInfo;
5151

@@ -60,8 +60,8 @@ public final class DefinitionMetadataMessage implements ServerMessage {
6060
private final short decimals;
6161

6262
private DefinitionMetadataMessage(@Nullable String database, String table, @Nullable String originTable,
63-
String column, @Nullable String originColumn, @Nullable String extendedTypeInfo, int collationId, long size, short typeId,
64-
int definitions, short decimals) {
63+
String column, @Nullable String originColumn, @Nullable String extendedTypeInfo, int collationId,
64+
long size, short typeId, int definitions, short decimals) {
6565
require(size >= 0, "size must not be a negative integer");
6666

6767
this.database = database;
@@ -100,9 +100,10 @@ public int getDefinitions() {
100100
public short getDecimals() {
101101
return decimals;
102102
}
103-
103+
104+
@Nullable
104105
public String getExtendedTypeInfo() {
105-
return extendedTypeInfo;
106+
return extendedTypeInfo;
106107
}
107108

108109
@Override
@@ -136,9 +137,9 @@ public int hashCode() {
136137
@Override
137138
public String toString() {
138139
return "DefinitionMetadataMessage{database='" + database + "', table='" + table + "' (origin:'" +
139-
originTable + "'), column='" + column + "' (origin:'" + originColumn + "'), extendedTypeInfo=" +
140-
extendedTypeInfo + ", collationId=" +collationId + ", size=" + size + ", type=" + typeId +
141-
", definitions=" + definitions + ", decimals=" + decimals + '}';
140+
originTable + "'), column='" + column + "' (origin:'" + originColumn + "'), extendedTypeInfo='" +
141+
extendedTypeInfo + "', collationId=" + collationId + ", size=" + size + ", type=" + typeId +
142+
", definitions=" + definitions + ", decimals=" + decimals + '}';
142143
}
143144

144145
static DefinitionMetadataMessage decode(ByteBuf buf, ConnectionContext context) {
@@ -179,10 +180,10 @@ private static DefinitionMetadataMessage decode41(ByteBuf buf, ConnectionContext
179180
String originTable = readVarIntSizedString(buf, charset);
180181
String column = readVarIntSizedString(buf, charset);
181182
String originColumn = readVarIntSizedString(buf, charset);
182-
183+
183184
String extendTypeInfo = null;
184185
if (context.getCapability().isMariaDb() && context.getCapability().isExtendedTypeInfo()) {
185-
extendTypeInfo = readVarIntSizedString(buf, charset);
186+
extendTypeInfo = readVarIntSizedString(buf, charset);
186187
}
187188

188189
// Skip constant 0x0c encoded by var integer
@@ -193,8 +194,8 @@ private static DefinitionMetadataMessage decode41(ByteBuf buf, ConnectionContext
193194
short typeId = buf.readUnsignedByte();
194195
int definitions = buf.readUnsignedShortLE();
195196

196-
return new DefinitionMetadataMessage(database, table, originTable, column, originColumn, extendTypeInfo, collationId,
197-
size, typeId, definitions, buf.readUnsignedByte());
197+
return new DefinitionMetadataMessage(database, table, originTable, column, originColumn,
198+
extendTypeInfo, collationId, size, typeId, definitions, buf.readUnsignedByte());
198199
}
199200

200201
private static String readVarIntSizedString(ByteBuf buf, Charset charset) {

r2dbc-mysql/src/test/java/io/asyncer/r2dbc/mysql/MariaDbIntegrationTestSupport.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,14 @@
1616

1717
package io.asyncer.r2dbc.mysql;
1818

19+
import io.asyncer.r2dbc.mysql.api.MySqlColumnMetadata;
1920
import io.asyncer.r2dbc.mysql.api.MySqlConnection;
21+
import io.asyncer.r2dbc.mysql.api.MySqlRow;
22+
import io.asyncer.r2dbc.mysql.api.MySqlRowMetadata;
2023
import io.r2dbc.spi.Readable;
24+
import io.r2dbc.spi.Row;
25+
import io.r2dbc.spi.RowMetadata;
26+
2127
import org.junit.jupiter.api.Test;
2228
import reactor.core.publisher.Mono;
2329

@@ -141,6 +147,22 @@ void returningGetRowUpdated() {
141147
.doOnNext(it -> assertThat(it).isEqualTo(2)));
142148
}
143149

150+
@Test
151+
void returningExtendedTypeInfoJson() {
152+
complete(conn -> changeCapability(conn).createStatement("CREATE TEMPORARY TABLE test(" +
153+
"id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value JSON NOT NULL)")
154+
.execute()
155+
.flatMap(IntegrationTestSupport::extractRowsUpdated)
156+
.thenMany(conn.createStatement("INSERT INTO test(value) VALUES (?)")
157+
.bind(0, "'{\"abc\": 123}'")
158+
.returnGeneratedValues()
159+
.execute())
160+
.flatMap(result -> result.map(DataEntity::readExtendedTypeInfoResult))
161+
.collectList()
162+
.doOnNext(list -> assertThat(list.get(0)).isEqualTo(true))
163+
);
164+
}
165+
144166
private static Mono<Void> assertWithSelectAll(MySqlConnection conn, Mono<List<DataEntity>> returning) {
145167
return returning.zipWhen(list -> conn.createStatement("SELECT * FROM test WHERE id IN (?,?,?,?,?)")
146168
.bind(0, list.get(0).getId())
@@ -171,6 +193,12 @@ private static Mono<Void> assertWithoutCreatedAt(MySqlConnection conn, Mono<List
171193
.then();
172194
}
173195

196+
private static MySqlConnection changeCapability(MySqlConnection conn) {
197+
ConnectionContext ctxt = ((MySqlSimpleConnection) conn).context();
198+
ctxt.initHandshake(ctxt.getConnectionId(), ctxt.getServerVersion(), Capability.DEFAULT_MARIADB);
199+
return conn;
200+
}
201+
174202
private static final class DataEntity {
175203

176204
private final int id;
@@ -250,5 +278,11 @@ static DataEntity withoutCreatedAt(Readable readable) {
250278

251279
return new DataEntity(id, value, ZonedDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC));
252280
}
281+
282+
static Boolean readExtendedTypeInfoResult(Row row, RowMetadata rowMetadata) {
283+
Boolean extendedTypeInfoResult = ((MySqlRowMetadata)rowMetadata)
284+
.getColumnMetadata("value").getNativeTypeMetadata().isMariaDbJson();
285+
return extendedTypeInfoResult;
286+
}
253287
}
254288
}

0 commit comments

Comments
 (0)