Skip to content

Commit 830cb34

Browse files
author
akonyaev
committed
add support for decimal types in ClickHouseRowBinaryStream
1 parent 25f22dd commit 830cb34

File tree

1 file changed

+61
-15
lines changed

1 file changed

+61
-15
lines changed

src/main/java/ru/yandex/clickhouse/util/ClickHouseRowBinaryStream.java

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88

99
import java.io.IOException;
1010
import java.io.OutputStream;
11+
import java.math.BigDecimal;
12+
import java.math.BigInteger;
1113
import java.nio.ByteBuffer;
1214
import java.nio.ByteOrder;
1315
import java.util.Date;
1416
import java.util.TimeZone;
1517
import java.util.UUID;
1618
import java.util.concurrent.TimeUnit;
1719

20+
import static com.google.common.primitives.Bytes.concat;
21+
1822
/**
1923
* @author Dmitry Andreev <a href="mailto:[email protected]"></a>
2024
*/
@@ -51,6 +55,7 @@ public void writeUnsignedLeb128(int value) throws IOException {
5155
/**
5256
* Dangerous. Can only be used for rare optimizations, for example when the string is written in parts
5357
* without prior concatenation. The size of the string in bytes must be passed through writeUnsignedLeb128.
58+
*
5459
* @param bytes byte array will be written into stream
5560
* @throws IOException in case if an I/O error occurs
5661
*/
@@ -163,19 +168,58 @@ public void writeFloat64(double value) throws IOException {
163168
out.writeDouble(value);
164169
}
165170

171+
public static void reverse(byte[] array) {
172+
if (array == null) {
173+
return;
174+
}
175+
int i = 0;
176+
int j = array.length - 1;
177+
byte tmp;
178+
while (j > i) {
179+
tmp = array[j];
180+
array[j] = array[i];
181+
array[i] = tmp;
182+
j--;
183+
i++;
184+
}
185+
}
186+
187+
byte[] bigDecimalToByte(BigDecimal num, int bytesLen, int scale) {
188+
BigDecimal ten = BigDecimal.valueOf(10);
189+
BigDecimal s = ten.pow(scale);
190+
BigInteger res = num.multiply(s).toBigInteger();
191+
byte[] r = res.toByteArray();
192+
reverse(r);
193+
return concat(r, new byte[bytesLen - r.length]);
194+
}
195+
196+
public void writeDecimal128(BigDecimal v, int scale) throws IOException {
197+
byte[] x = bigDecimalToByte(v, 16, scale);
198+
out.write(x);
199+
}
200+
201+
public void writeDecimal64(BigDecimal v, int scale) throws IOException {
202+
byte[] x = bigDecimalToByte(v, 8, scale);
203+
out.write(x);
204+
}
205+
206+
public void writeDecimal32(BigDecimal v, int scale) throws IOException {
207+
byte[] x = bigDecimalToByte(v, 4, scale);
208+
out.write(x);
209+
}
166210

167211
public void writeDateArray(Date[] dates) throws IOException {
168212
Preconditions.checkNotNull(dates);
169213
writeUnsignedLeb128(dates.length);
170-
for (Date date: dates) {
214+
for (Date date : dates) {
171215
writeDate(date);
172216
}
173217
}
174218

175219
public void writeDateTimeArray(Date[] dates) throws IOException {
176220
Preconditions.checkNotNull(dates);
177221
writeUnsignedLeb128(dates.length);
178-
for (Date date: dates) {
222+
for (Date date : dates) {
179223
writeDateTime(date);
180224
}
181225
}
@@ -191,92 +235,94 @@ public void writeStringArray(String[] strings) throws IOException {
191235
public void writeInt8Array(byte[] bytes) throws IOException {
192236
Preconditions.checkNotNull(bytes);
193237
writeUnsignedLeb128(bytes.length);
194-
for (byte b: bytes) {
238+
for (byte b : bytes) {
195239
writeInt8(b);
196240
}
197241
}
242+
198243
public void writeInt8Array(int[] ints) throws IOException {
199244
Preconditions.checkNotNull(ints);
200245
writeUnsignedLeb128(ints.length);
201-
for (int i: ints) {
246+
for (int i : ints) {
202247
writeInt8(i);
203248
}
204249
}
205250

206251
public void writeUInt8Array(int[] ints) throws IOException {
207252
Preconditions.checkNotNull(ints);
208253
writeUnsignedLeb128(ints.length);
209-
for (int i: ints) {
254+
for (int i : ints) {
210255
writeUInt8(i);
211256
}
212257
}
213258

214259
public void writeInt16Array(short[] shorts) throws IOException {
215260
Preconditions.checkNotNull(shorts);
216261
writeUnsignedLeb128(shorts.length);
217-
for (short s: shorts) {
262+
for (short s : shorts) {
218263
writeInt16(s);
219264
}
220265
}
221266

222267
public void writeUInt16Array(int[] ints) throws IOException {
223268
Preconditions.checkNotNull(ints);
224269
writeUnsignedLeb128(ints.length);
225-
for (int i: ints) {
270+
for (int i : ints) {
226271
writeUInt16(i);
227272
}
228273
}
229274

230275
public void writeInt32Array(int[] ints) throws IOException {
231276
Preconditions.checkNotNull(ints);
232277
writeUnsignedLeb128(ints.length);
233-
for (int i: ints) {
278+
for (int i : ints) {
234279
writeInt32(i);
235280
}
236281
}
237282

238283
public void writeUInt32Array(long[] longs) throws IOException {
239284
Preconditions.checkNotNull(longs);
240285
writeUnsignedLeb128(longs.length);
241-
for (long l: longs) {
286+
for (long l : longs) {
242287
writeUInt32(l);
243288
}
244289
}
245290

246291
public void writeInt64Array(long[] longs) throws IOException {
247292
Preconditions.checkNotNull(longs);
248293
writeUnsignedLeb128(longs.length);
249-
for (long l: longs) {
294+
for (long l : longs) {
250295
writeInt64(l);
251296
}
252297
}
253298

254299
public void writeUInt64Array(long[] longs) throws IOException {
255300
Preconditions.checkNotNull(longs);
256301
writeUnsignedLeb128(longs.length);
257-
for (long l: longs) {
302+
for (long l : longs) {
258303
writeUInt64(l);
259304
}
260305
}
261306

262307
public void writeFloat32Array(float[] floats) throws IOException {
263308
Preconditions.checkNotNull(floats);
264309
writeUnsignedLeb128(floats.length);
265-
for (float f: floats) {
310+
for (float f : floats) {
266311
writeFloat32(f);
267312
}
268313
}
269314

270315
public void writeFloat64Array(double[] doubles) throws IOException {
271316
Preconditions.checkNotNull(doubles);
272317
writeUnsignedLeb128(doubles.length);
273-
for (double d: doubles) {
318+
for (double d : doubles) {
274319
writeFloat64(d);
275320
}
276321
}
277322

278-
/** Write a marker indicating if value is nullable or not.
279-
*
323+
/**
324+
* Write a marker indicating if value is nullable or not.
325+
* <p>
280326
* E.g., to write Nullable(Int32):
281327
*
282328
* <pre>

0 commit comments

Comments
 (0)