19
19
package org .apache .flink .connector .jdbc .table ;
20
20
21
21
import org .apache .flink .annotation .Internal ;
22
+ import org .apache .flink .annotation .VisibleForTesting ;
23
+ import org .apache .flink .api .common .eventtime .WatermarkStrategy ;
24
+ import org .apache .flink .api .connector .source .Boundedness ;
22
25
import org .apache .flink .connector .jdbc .dialect .JdbcDialect ;
23
26
import org .apache .flink .connector .jdbc .internal .options .InternalJdbcConnectionOptions ;
24
27
import org .apache .flink .connector .jdbc .internal .options .JdbcReadOptions ;
28
+ import org .apache .flink .connector .jdbc .source .JdbcSource ;
29
+ import org .apache .flink .connector .jdbc .source .JdbcSourceBuilder ;
25
30
import org .apache .flink .connector .jdbc .split .CompositeJdbcParameterValuesProvider ;
26
31
import org .apache .flink .connector .jdbc .split .JdbcGenericParameterValuesProvider ;
27
32
import org .apache .flink .connector .jdbc .split .JdbcNumericBetweenParametersProvider ;
28
33
import org .apache .flink .connector .jdbc .split .JdbcParameterValuesProvider ;
34
+ import org .apache .flink .streaming .api .datastream .DataStream ;
35
+ import org .apache .flink .streaming .api .datastream .DataStreamSource ;
36
+ import org .apache .flink .streaming .api .environment .StreamExecutionEnvironment ;
29
37
import org .apache .flink .table .connector .ChangelogMode ;
30
38
import org .apache .flink .table .connector .Projection ;
39
+ import org .apache .flink .table .connector .ProviderContext ;
40
+ import org .apache .flink .table .connector .source .DataStreamScanProvider ;
31
41
import org .apache .flink .table .connector .source .DynamicTableSource ;
32
- import org .apache .flink .table .connector .source .InputFormatProvider ;
33
42
import org .apache .flink .table .connector .source .LookupTableSource ;
34
43
import org .apache .flink .table .connector .source .ScanTableSource ;
35
44
import org .apache .flink .table .connector .source .abilities .SupportsFilterPushDown ;
38
47
import org .apache .flink .table .connector .source .lookup .LookupFunctionProvider ;
39
48
import org .apache .flink .table .connector .source .lookup .PartialCachingLookupProvider ;
40
49
import org .apache .flink .table .connector .source .lookup .cache .LookupCache ;
50
+ import org .apache .flink .table .data .RowData ;
41
51
import org .apache .flink .table .expressions .CallExpression ;
42
52
import org .apache .flink .table .expressions .ResolvedExpression ;
43
53
import org .apache .flink .table .types .DataType ;
@@ -68,6 +78,8 @@ public class JdbcDynamicTableSource
68
78
SupportsFilterPushDown {
69
79
private static final Logger LOG = LoggerFactory .getLogger (JdbcDynamicTableSource .class );
70
80
81
+ private static final String JDBC_TRANSFORMATION = "jdbc" ;
82
+
71
83
private final InternalJdbcConnectionOptions options ;
72
84
private final JdbcReadOptions readOptions ;
73
85
private final int lookupMaxRetryTimes ;
@@ -77,19 +89,33 @@ public class JdbcDynamicTableSource
77
89
private long limit = -1 ;
78
90
private List <String > resolvedPredicates = new ArrayList <>();
79
91
private Serializable [] pushdownParams = new Serializable [0 ];
92
+ // The Nullable for iterative.
93
+ @ Nullable protected final String tableIdentifier ;
80
94
95
+ @ VisibleForTesting
81
96
public JdbcDynamicTableSource (
82
97
InternalJdbcConnectionOptions options ,
83
98
JdbcReadOptions readOptions ,
84
99
int lookupMaxRetryTimes ,
85
100
@ Nullable LookupCache cache ,
86
101
DataType physicalRowDataType ) {
102
+ this (options , readOptions , lookupMaxRetryTimes , cache , physicalRowDataType , null );
103
+ }
104
+
105
+ public JdbcDynamicTableSource (
106
+ InternalJdbcConnectionOptions options ,
107
+ JdbcReadOptions readOptions ,
108
+ int lookupMaxRetryTimes ,
109
+ @ Nullable LookupCache cache ,
110
+ DataType physicalRowDataType ,
111
+ String tableIdentifier ) {
87
112
this .options = options ;
88
113
this .readOptions = readOptions ;
89
114
this .lookupMaxRetryTimes = lookupMaxRetryTimes ;
90
115
this .cache = cache ;
91
116
this .physicalRowDataType = physicalRowDataType ;
92
117
this .dialectName = options .getDialect ().dialectName ();
118
+ this .tableIdentifier = tableIdentifier ;
93
119
}
94
120
95
121
@ Override
@@ -121,17 +147,18 @@ public LookupRuntimeProvider getLookupRuntimeProvider(LookupContext context) {
121
147
}
122
148
123
149
@ Override
124
- public ScanRuntimeProvider getScanRuntimeProvider (ScanContext runtimeProviderContext ) {
125
- final JdbcRowDataInputFormat .Builder builder =
126
- JdbcRowDataInputFormat .builder ()
127
- .setDrivername (options .getDriverName ())
150
+ public ScanRuntimeProvider getScanRuntimeProvider (ScanContext scanContext ) {
151
+
152
+ final JdbcSourceBuilder <RowData > builder =
153
+ JdbcSource .<RowData >builder ()
154
+ .setDriverName (options .getDriverName ())
128
155
.setDBUrl (options .getDbURL ())
129
156
.setUsername (options .getUsername ().orElse (null ))
130
157
.setPassword (options .getPassword ().orElse (null ))
131
158
.setAutoCommit (readOptions .getAutoCommit ());
132
159
133
160
if (readOptions .getFetchSize () != 0 ) {
134
- builder .setFetchSize (readOptions .getFetchSize ());
161
+ builder .setResultSetFetchSize (readOptions .getFetchSize ());
135
162
}
136
163
final JdbcDialect dialect = options .getDialect ();
137
164
String query =
@@ -153,13 +180,13 @@ public ScanRuntimeProvider getScanRuntimeProvider(ScanContext runtimeProviderCon
153
180
.ofBatchNum (numPartitions ),
154
181
new JdbcGenericParameterValuesProvider (allPushdownParams ));
155
182
156
- builder .setParametersProvider (allParams );
183
+ builder .setJdbcParameterValuesProvider (allParams );
157
184
158
185
predicates .add (
159
186
dialect .quoteIdentifier (readOptions .getPartitionColumnName ().get ())
160
187
+ " BETWEEN ? AND ?" );
161
188
} else {
162
- builder .setParametersProvider (
189
+ builder .setJdbcParameterValuesProvider (
163
190
new JdbcGenericParameterValuesProvider (replicatePushdownParamsForN (1 )));
164
191
}
165
192
@@ -179,13 +206,34 @@ public ScanRuntimeProvider getScanRuntimeProvider(ScanContext runtimeProviderCon
179
206
180
207
LOG .debug ("Query generated for JDBC scan: " + query );
181
208
182
- builder .setQuery (query );
209
+ builder .setSql (query );
183
210
final RowType rowType = (RowType ) physicalRowDataType .getLogicalType ();
184
- builder .setRowConverter (dialect .getRowConverter (rowType ));
185
- builder .setRowDataTypeInfo (
186
- runtimeProviderContext .createTypeInformation (physicalRowDataType ));
211
+ builder .setResultExtractor (new RowDataResultExtractor (dialect .getRowConverter (rowType )));
212
+ builder .setTypeInformation (scanContext .createTypeInformation (physicalRowDataType ));
213
+ options .getProperties ()
214
+ .forEach (
215
+ (key , value ) ->
216
+ builder .setConnectionProperty (key .toString (), value .toString ()));
217
+ JdbcSource <RowData > source = builder .build ();
218
+ return new DataStreamScanProvider () {
219
+ @ Override
220
+ public DataStream <RowData > produceDataStream (
221
+ ProviderContext providerContext , StreamExecutionEnvironment execEnv ) {
222
+ String sourceName =
223
+ Objects .isNull (tableIdentifier )
224
+ ? "JdbcSource"
225
+ : "JdbcSource-" + tableIdentifier ;
226
+ DataStreamSource <RowData > sourceStream =
227
+ execEnv .fromSource (source , WatermarkStrategy .noWatermarks (), sourceName );
228
+ providerContext .generateUid (JDBC_TRANSFORMATION ).ifPresent (sourceStream ::uid );
229
+ return sourceStream ;
230
+ }
187
231
188
- return InputFormatProvider .of (builder .build ());
232
+ @ Override
233
+ public boolean isBounded () {
234
+ return source .getBoundedness () == Boundedness .BOUNDED ;
235
+ }
236
+ };
189
237
}
190
238
191
239
@ Override
@@ -208,7 +256,12 @@ public void applyProjection(int[][] projectedFields, DataType producedDataType)
208
256
public DynamicTableSource copy () {
209
257
JdbcDynamicTableSource newSource =
210
258
new JdbcDynamicTableSource (
211
- options , readOptions , lookupMaxRetryTimes , cache , physicalRowDataType );
259
+ options ,
260
+ readOptions ,
261
+ lookupMaxRetryTimes ,
262
+ cache ,
263
+ physicalRowDataType ,
264
+ tableIdentifier );
212
265
newSource .resolvedPredicates = new ArrayList <>(this .resolvedPredicates );
213
266
newSource .pushdownParams = Arrays .copyOf (this .pushdownParams , this .pushdownParams .length );
214
267
return newSource ;
@@ -236,7 +289,8 @@ public boolean equals(Object o) {
236
289
&& Objects .equals (dialectName , that .dialectName )
237
290
&& Objects .equals (limit , that .limit )
238
291
&& Objects .equals (resolvedPredicates , that .resolvedPredicates )
239
- && Arrays .deepEquals (pushdownParams , that .pushdownParams );
292
+ && Arrays .deepEquals (pushdownParams , that .pushdownParams )
293
+ && Objects .equals (tableIdentifier , that .tableIdentifier );
240
294
}
241
295
242
296
@ Override
@@ -250,7 +304,8 @@ public int hashCode() {
250
304
dialectName ,
251
305
limit ,
252
306
resolvedPredicates ,
253
- pushdownParams );
307
+ pushdownParams ,
308
+ tableIdentifier );
254
309
}
255
310
256
311
@ Override
0 commit comments