0
# Result Set Processing
1
2
Comprehensive result set processing capabilities with support for all Java primitive types, temporal data, decimal precision, and complex data structures including Maps. Provides both index-based and label-based data access with complete type conversion support.
3
4
## Capabilities
5
6
### Result Set Navigation
7
8
FlinkResultSet provides forward-only cursor navigation through query results with proper resource management.
9
10
```java { .api }
11
public class FlinkResultSet extends BaseResultSet {
12
public FlinkResultSet(Statement statement, StatementResult result);
13
public FlinkResultSet(Statement statement, CloseableResultIterator<RowData> iterator, ResolvedSchema schema);
14
15
// Navigation
16
public boolean next() throws SQLException;
17
public void close() throws SQLException;
18
public boolean isClosed() throws SQLException;
19
public boolean wasNull() throws SQLException;
20
21
// Metadata access
22
public ResultSetMetaData getMetaData() throws SQLException;
23
public Statement getStatement() throws SQLException;
24
public int findColumn(String columnLabel) throws SQLException;
25
}
26
```
27
28
**Usage Example:**
29
```java
30
Statement statement = connection.createStatement();
31
ResultSet results = statement.executeQuery("SELECT id, name, balance FROM accounts");
32
33
try {
34
while (results.next()) {
35
int id = results.getInt(1);
36
String name = results.getString(2);
37
double balance = results.getDouble(3);
38
39
System.out.printf("Account %d: %s has balance $%.2f%n", id, name, balance);
40
}
41
} finally {
42
results.close();
43
}
44
```
45
46
### Primitive Data Type Retrieval
47
48
Retrieve primitive Java data types by column index or label with automatic type conversion.
49
50
```java { .api }
51
public class FlinkResultSet extends BaseResultSet {
52
// By column index (1-based)
53
public boolean getBoolean(int columnIndex) throws SQLException;
54
public byte getByte(int columnIndex) throws SQLException;
55
public short getShort(int columnIndex) throws SQLException;
56
public int getInt(int columnIndex) throws SQLException;
57
public long getLong(int columnIndex) throws SQLException;
58
public float getFloat(int columnIndex) throws SQLException;
59
public double getDouble(int columnIndex) throws SQLException;
60
61
// By column label
62
public boolean getBoolean(String columnLabel) throws SQLException;
63
public byte getByte(String columnLabel) throws SQLException;
64
public short getShort(String columnLabel) throws SQLException;
65
public int getInt(String columnLabel) throws SQLException;
66
public long getLong(String columnLabel) throws SQLException;
67
public float getFloat(String columnLabel) throws SQLException;
68
public double getDouble(String columnLabel) throws SQLException;
69
}
70
```
71
72
**Usage Example:**
73
```java
74
ResultSet results = statement.executeQuery(
75
"SELECT order_id, quantity, price, is_shipped, tax_rate " +
76
"FROM orders WHERE status = 'completed'"
77
);
78
79
while (results.next()) {
80
// Access by index
81
int orderId = results.getInt(1);
82
short quantity = results.getShort(2);
83
double price = results.getDouble(3);
84
boolean isShipped = results.getBoolean(4);
85
float taxRate = results.getFloat(5);
86
87
// Or access by column name
88
int orderIdByName = results.getInt("order_id");
89
short quantityByName = results.getShort("quantity");
90
91
System.out.printf("Order %d: %d items at $%.2f (shipped: %b, tax: %.2f%%)%n",
92
orderId, quantity, price, isShipped, taxRate * 100);
93
}
94
```
95
96
### String and Binary Data Retrieval
97
98
Retrieve string and binary data with comprehensive character encoding support.
99
100
```java { .api }
101
public class FlinkResultSet extends BaseResultSet {
102
// String data
103
public String getString(int columnIndex) throws SQLException;
104
public String getString(String columnLabel) throws SQLException;
105
106
// Binary data
107
public byte[] getBytes(int columnIndex) throws SQLException;
108
public byte[] getBytes(String columnLabel) throws SQLException;
109
}
110
```
111
112
**Usage Example:**
113
```java
114
ResultSet results = statement.executeQuery(
115
"SELECT user_id, username, profile_data, avatar_image " +
116
"FROM user_profiles"
117
);
118
119
while (results.next()) {
120
int userId = results.getInt("user_id");
121
String username = results.getString("username");
122
String profileData = results.getString("profile_data"); // JSON string
123
byte[] avatarImage = results.getBytes("avatar_image"); // Binary data
124
125
System.out.printf("User %d (%s): %d bytes profile, %d bytes avatar%n",
126
userId, username, profileData.length(), avatarImage.length);
127
}
128
```
129
130
### Decimal and Numeric Data Retrieval
131
132
Handle high-precision decimal numbers with configurable scale and precision.
133
134
```java { .api }
135
public class FlinkResultSet extends BaseResultSet {
136
public BigDecimal getBigDecimal(int columnIndex) throws SQLException;
137
public BigDecimal getBigDecimal(String columnLabel) throws SQLException;
138
139
// Deprecated method with scale parameter
140
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException;
141
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException;
142
}
143
```
144
145
**Usage Example:**
146
```java
147
ResultSet results = statement.executeQuery(
148
"SELECT product_id, price, discount_rate, tax_amount " +
149
"FROM financial_transactions " +
150
"WHERE amount > 1000.00"
151
);
152
153
while (results.next()) {
154
int productId = results.getInt("product_id");
155
BigDecimal price = results.getBigDecimal("price");
156
BigDecimal discountRate = results.getBigDecimal("discount_rate");
157
BigDecimal taxAmount = results.getBigDecimal("tax_amount");
158
159
// Calculate final amount with precision
160
BigDecimal discountAmount = price.multiply(discountRate);
161
BigDecimal finalAmount = price.subtract(discountAmount).add(taxAmount);
162
163
System.out.printf("Product %d: $%s (discount: $%s, tax: $%s, final: $%s)%n",
164
productId, price, discountAmount, taxAmount, finalAmount);
165
}
166
```
167
168
### Temporal Data Retrieval
169
170
Retrieve date, time, and timestamp data with proper Java temporal type support.
171
172
```java { .api }
173
public class FlinkResultSet extends BaseResultSet {
174
public Date getDate(int columnIndex) throws SQLException;
175
public Date getDate(String columnLabel) throws SQLException;
176
177
public Time getTime(int columnIndex) throws SQLException;
178
public Time getTime(String columnLabel) throws SQLException;
179
180
public Timestamp getTimestamp(int columnIndex) throws SQLException;
181
public Timestamp getTimestamp(String columnLabel) throws SQLException;
182
}
183
```
184
185
**Usage Example:**
186
```java
187
ResultSet results = statement.executeQuery(
188
"SELECT event_id, event_date, start_time, created_timestamp " +
189
"FROM events " +
190
"WHERE event_date >= CURRENT_DATE"
191
);
192
193
while (results.next()) {
194
int eventId = results.getInt("event_id");
195
Date eventDate = results.getDate("event_date");
196
Time startTime = results.getTime("start_time");
197
Timestamp createdTimestamp = results.getTimestamp("created_timestamp");
198
199
System.out.printf("Event %d on %s at %s (created: %s)%n",
200
eventId, eventDate, startTime, createdTimestamp);
201
}
202
```
203
204
### Generic Object Retrieval
205
206
Retrieve any column as a generic Object for dynamic processing or complex data types.
207
208
```java { .api }
209
public class FlinkResultSet extends BaseResultSet {
210
public Object getObject(int columnIndex) throws SQLException;
211
public Object getObject(String columnLabel) throws SQLException;
212
}
213
```
214
215
**Usage Example:**
216
```java
217
ResultSet results = statement.executeQuery(
218
"SELECT id, data_column, map_column " +
219
"FROM mixed_data_table"
220
);
221
222
while (results.next()) {
223
int id = results.getInt("id");
224
Object data = results.getObject("data_column");
225
Object mapData = results.getObject("map_column"); // Returns Map for Flink MAP type
226
227
System.out.printf("ID %d: data type=%s, map type=%s%n",
228
id, data.getClass().getSimpleName(), mapData.getClass().getSimpleName());
229
230
// Handle Map data
231
if (mapData instanceof Map) {
232
Map<?, ?> map = (Map<?, ?>) mapData;
233
System.out.println("Map contents: " + map);
234
}
235
}
236
```
237
238
### Null Value Handling
239
240
Proper null value detection and handling for all data types.
241
242
```java { .api }
243
public class FlinkResultSet extends BaseResultSet {
244
public boolean wasNull() throws SQLException;
245
}
246
```
247
248
**Usage Example:**
249
```java
250
ResultSet results = statement.executeQuery(
251
"SELECT customer_id, email, phone_number " +
252
"FROM customers"
253
);
254
255
while (results.next()) {
256
int customerId = results.getInt("customer_id");
257
258
String email = results.getString("email");
259
boolean emailWasNull = results.wasNull();
260
261
String phoneNumber = results.getString("phone_number");
262
boolean phoneWasNull = results.wasNull();
263
264
System.out.printf("Customer %d: email=%s, phone=%s%n",
265
customerId,
266
emailWasNull ? "NULL" : email,
267
phoneWasNull ? "NULL" : phoneNumber);
268
}
269
```
270
271
### Result Set Metadata Access
272
273
Access comprehensive metadata about result set structure and column information.
274
275
```java { .api }
276
public class FlinkResultSetMetaData implements ResultSetMetaData {
277
public FlinkResultSetMetaData(List<String> columnNames, List<DataType> columnTypes);
278
279
// Column information
280
public int getColumnCount() throws SQLException;
281
public String getColumnName(int column) throws SQLException;
282
public String getColumnLabel(int column) throws SQLException;
283
public int getColumnType(int column) throws SQLException;
284
public String getColumnTypeName(int column) throws SQLException;
285
public String getColumnClassName(int column) throws SQLException;
286
287
// Numeric metadata
288
public int getPrecision(int column) throws SQLException;
289
public int getScale(int column) throws SQLException;
290
public int getColumnDisplaySize(int column) throws SQLException;
291
292
// Column properties
293
public int isNullable(int column) throws SQLException;
294
public boolean isSigned(int column) throws SQLException;
295
public boolean isAutoIncrement(int column) throws SQLException; // Always false
296
public boolean isCaseSensitive(int column) throws SQLException; // Always false
297
public boolean isSearchable(int column) throws SQLException; // Always true
298
public boolean isCurrency(int column) throws SQLException; // Always false
299
public boolean isReadOnly(int column) throws SQLException; // Always true
300
public boolean isWritable(int column) throws SQLException; // Always false
301
public boolean isDefinitelyWritable(int column) throws SQLException; // Always false
302
}
303
```
304
305
**Usage Example:**
306
```java
307
ResultSet results = statement.executeQuery("SELECT * FROM sales_data");
308
ResultSetMetaData metadata = results.getMetaData();
309
310
int columnCount = metadata.getColumnCount();
311
System.out.println("Result set has " + columnCount + " columns:");
312
313
for (int i = 1; i <= columnCount; i++) {
314
String columnName = metadata.getColumnName(i);
315
String columnType = metadata.getColumnTypeName(i);
316
int precision = metadata.getPrecision(i);
317
int scale = metadata.getScale(i);
318
boolean nullable = metadata.isNullable(i) == ResultSetMetaData.columnNullable;
319
320
System.out.printf("Column %d: %s (%s) precision=%d scale=%d nullable=%b%n",
321
i, columnName, columnType, precision, scale, nullable);
322
}
323
324
// Process data
325
while (results.next()) {
326
for (int i = 1; i <= columnCount; i++) {
327
Object value = results.getObject(i);
328
boolean wasNull = results.wasNull();
329
System.out.printf("%s=%s ", metadata.getColumnName(i),
330
wasNull ? "NULL" : value.toString());
331
}
332
System.out.println();
333
}
334
```
335
336
### Column Index Resolution
337
338
Convert column labels to indices for efficient repeated access.
339
340
```java { .api }
341
public class FlinkResultSet extends BaseResultSet {
342
public int findColumn(String columnLabel) throws SQLException;
343
}
344
```
345
346
**Usage Example:**
347
```java
348
ResultSet results = statement.executeQuery(
349
"SELECT customer_id, first_name, last_name, email " +
350
"FROM customers ORDER BY last_name"
351
);
352
353
// Get column indices once for efficiency
354
int customerIdIndex = results.findColumn("customer_id");
355
int firstNameIndex = results.findColumn("first_name");
356
int lastNameIndex = results.findColumn("last_name");
357
int emailIndex = results.findColumn("email");
358
359
while (results.next()) {
360
// Use indices for faster access
361
int customerId = results.getInt(customerIdIndex);
362
String firstName = results.getString(firstNameIndex);
363
String lastName = results.getString(lastNameIndex);
364
String email = results.getString(emailIndex);
365
366
System.out.printf("Customer %d: %s %s <%s>%n",
367
customerId, firstName, lastName, email);
368
}
369
```
370
371
### Data Type Mapping
372
373
Understanding how Flink data types map to Java types:
374
375
**Primitive Types:**
376
- `BOOLEAN` → `boolean`
377
- `TINYINT` → `byte`
378
- `SMALLINT` → `short`
379
- `INT` → `int`
380
- `BIGINT` → `long`
381
- `FLOAT` → `float`
382
- `DOUBLE` → `double`
383
384
**Text Types:**
385
- `CHAR`, `VARCHAR`, `STRING` → `String`
386
- `BINARY`, `VARBINARY` → `byte[]`
387
388
**Numeric Types:**
389
- `DECIMAL(p,s)` → `BigDecimal`
390
391
**Temporal Types:**
392
- `DATE` → `java.sql.Date`
393
- `TIME` → `java.sql.Time`
394
- `TIMESTAMP` → `java.sql.Timestamp`
395
396
**Complex Types:**
397
- `MAP<K,V>` → `java.util.Map<K,V>`
398
- `ARRAY<T>` → Not supported (throws SQLFeatureNotSupportedException)
399
- `ROW(...)` → Object representation
400
401
### Unsupported Result Set Features
402
403
The following JDBC ResultSet features are not supported:
404
405
- **Array Data**: `getArray()` methods throw `SQLFeatureNotSupportedException`
406
- **Streaming Data**: `getAsciiStream()`, `getBinaryStream()`, `getCharacterStream()`
407
- **Result Set Updates**: All `updateXXX()` methods
408
- **Cursor Movement**: `previous()`, `first()`, `last()`, `absolute()`, `relative()`
409
- **Row Operations**: `insertRow()`, `updateRow()`, `deleteRow()`, `refreshRow()`
410
- **Timezone-Aware Methods**: Date/time methods with Calendar parameters
411
412
### Performance Optimization
413
414
**Column Access Patterns:**
415
```java
416
// Efficient: Access columns in order
417
while (results.next()) {
418
int col1 = results.getInt(1); // Good
419
String col2 = results.getString(2); // Good
420
double col3 = results.getDouble(3); // Good
421
}
422
423
// Less efficient: Random column access
424
while (results.next()) {
425
double col3 = results.getDouble(3); // OK but not optimal
426
int col1 = results.getInt(1); // OK but not optimal
427
String col2 = results.getString(2); // OK but not optimal
428
}
429
```
430
431
**Resource Management:**
432
```java
433
// Always close result sets
434
try (Statement stmt = connection.createStatement();
435
ResultSet results = stmt.executeQuery("SELECT * FROM large_table")) {
436
437
while (results.next()) {
438
// Process rows efficiently
439
}
440
// Automatic cleanup with try-with-resources
441
}
442
```
443
444
### Error Handling
445
446
Common result set processing errors:
447
448
**Column Not Found:**
449
```java
450
try {
451
String value = results.getString("nonexistent_column");
452
} catch (SQLException e) {
453
System.err.println("Column not found: " + e.getMessage());
454
}
455
```
456
457
**Type Conversion Error:**
458
```java
459
try {
460
int value = results.getInt("text_column"); // Contains "abc"
461
} catch (SQLException e) {
462
System.err.println("Type conversion failed: " + e.getMessage());
463
}
464
```
465
466
**Result Set Closed:**
467
```java
468
results.close();
469
try {
470
results.next();
471
} catch (SQLException e) {
472
System.err.println("Result set is closed: " + e.getMessage());
473
}
474
```