@@ -6,11 +6,11 @@ package io.airbyte.integrations.source.mssql
66
77import com.fasterxml.jackson.databind.JsonNode
88import com.fasterxml.jackson.databind.node.BinaryNode
9- import com.fasterxml.jackson.databind.node.ObjectNode
109import io.airbyte.cdk.command.OpaqueStateValue
1110import io.airbyte.cdk.data.LeafAirbyteSchemaType
1211import io.airbyte.cdk.data.OffsetDateTimeCodec
13- import io.airbyte.cdk.discover.Field
12+ import io.airbyte.cdk.discover.EmittedField
13+ import io.airbyte.cdk.output.sockets.toJson
1414import io.airbyte.cdk.read.And
1515import io.airbyte.cdk.read.DefaultJdbcStreamState
1616import io.airbyte.cdk.read.Equal
@@ -29,6 +29,7 @@ import io.airbyte.cdk.read.Or
2929import io.airbyte.cdk.read.OrderBy
3030import io.airbyte.cdk.read.SelectColumnMaxValue
3131import io.airbyte.cdk.read.SelectColumns
32+ import io.airbyte.cdk.read.SelectQuerier
3233import io.airbyte.cdk.read.SelectQuery
3334import io.airbyte.cdk.read.SelectQueryGenerator
3435import io.airbyte.cdk.read.SelectQuerySpec
@@ -74,7 +75,7 @@ private fun getEffectiveCursorCheckpoint(
7475 * Converts a state value string to a JsonNode based on the field type. This function handles type
7576 * conversions and date formatting for state checkpoints.
7677 */
77- fun stateValueToJsonNode (field : Field , stateValue : String? ): JsonNode {
78+ fun stateValueToJsonNode (field : EmittedField , stateValue : String? ): JsonNode {
7879 when (field.type.airbyteSchemaType) {
7980 is LeafAirbyteSchemaType ->
8081 return when (field.type.airbyteSchemaType as LeafAirbyteSchemaType ) {
@@ -185,7 +186,7 @@ class MsSqlServerJdbcNonResumableSnapshotPartition(
185186class MsSqlServerJdbcNonResumableSnapshotWithCursorPartition (
186187 selectQueryGenerator : SelectQueryGenerator ,
187188 streamState : DefaultJdbcStreamState ,
188- val cursor : Field ,
189+ val cursor : EmittedField ,
189190 val cursorCutoffTime : JsonNode ? = null ,
190191) :
191192 MsSqlServerJdbcPartition (selectQueryGenerator, streamState),
@@ -232,7 +233,7 @@ class MsSqlServerJdbcNonResumableSnapshotWithCursorPartition(
232233sealed class MsSqlServerJdbcResumablePartition (
233234 selectQueryGenerator : SelectQueryGenerator ,
234235 streamState : DefaultJdbcStreamState ,
235- val checkpointColumns : List <Field >,
236+ val checkpointColumns : List <EmittedField >,
236237) :
237238 MsSqlServerJdbcPartition (selectQueryGenerator, streamState),
238239 JdbcSplittablePartition <DefaultJdbcStreamState > {
@@ -262,7 +263,7 @@ sealed class MsSqlServerJdbcResumablePartition(
262263 val querySpec =
263264 SelectQuerySpec (
264265 SelectColumns (stream.fields + checkpointColumns),
265- FromSample (stream.name, stream.namespace, sampleRateInvPow2, sampleSize),
266+ FromSample (stream.name, stream.namespace, sampleRateInvPow2, sampleSize, where ),
266267 NoWhere ,
267268 OrderBy (checkpointColumns),
268269 Limit (sampleSize.toLong())
@@ -272,34 +273,35 @@ sealed class MsSqlServerJdbcResumablePartition(
272273
273274 val where: Where
274275 get() {
275- val zippedLowerBound: List <Pair <Field , JsonNode >> =
276+ val zippedLowerBound: List <Pair <EmittedField , JsonNode >> =
276277 lowerBound?.let { checkpointColumns.zip(it) } ? : listOf ()
277278 val lowerBoundDisj: List <WhereClauseNode > =
278- zippedLowerBound.mapIndexed { idx: Int , (gtCol: Field , gtValue: JsonNode ) ->
279+ zippedLowerBound.mapIndexed { idx: Int , (gtCol: EmittedField , gtValue: JsonNode ) ->
279280 val lastLeaf: WhereClauseLeafNode =
280281 if (isLowerBoundIncluded && idx == checkpointColumns.size - 1 ) {
281282 GreaterOrEqual (gtCol, gtValue)
282283 } else {
283284 Greater (gtCol, gtValue)
284285 }
285286 And (
286- zippedLowerBound.take(idx).map { (eqCol: Field , eqValue: JsonNode ) ->
287+ zippedLowerBound.take(idx).map { (eqCol: EmittedField , eqValue: JsonNode ) ->
287288 Equal (eqCol, eqValue)
288289 } + listOf (lastLeaf),
289290 )
290291 }
291- val zippedUpperBound: List <Pair <Field , JsonNode >> =
292+ val zippedUpperBound: List <Pair <EmittedField , JsonNode >> =
292293 upperBound?.let { checkpointColumns.zip(it) } ? : listOf ()
293294 val upperBoundDisj: List <WhereClauseNode > =
294- zippedUpperBound.mapIndexed { idx: Int , (leqCol: Field , leqValue: JsonNode ) ->
295+ zippedUpperBound.mapIndexed { idx: Int , (leqCol: EmittedField , leqValue: JsonNode )
296+ ->
295297 val lastLeaf: WhereClauseLeafNode =
296298 if (idx < zippedUpperBound.size - 1 ) {
297299 Lesser (leqCol, leqValue)
298300 } else {
299301 LesserOrEqual (leqCol, leqValue)
300302 }
301303 And (
302- zippedUpperBound.take(idx).map { (eqCol: Field , eqValue: JsonNode ) ->
304+ zippedUpperBound.take(idx).map { (eqCol: EmittedField , eqValue: JsonNode ) ->
303305 Equal (eqCol, eqValue)
304306 } + listOf (lastLeaf),
305307 )
@@ -323,7 +325,7 @@ sealed class MsSqlServerJdbcResumablePartition(
323325class MsSqlServerJdbcRfrSnapshotPartition (
324326 selectQueryGenerator : SelectQueryGenerator ,
325327 streamState : DefaultJdbcStreamState ,
326- primaryKey : List <Field >,
328+ primaryKey : List <EmittedField >,
327329 override val lowerBound : List <JsonNode >? ,
328330 override val upperBound : List <JsonNode >? ,
329331) : MsSqlServerJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) {
@@ -341,18 +343,19 @@ class MsSqlServerJdbcRfrSnapshotPartition(
341343 )
342344 }
343345
344- override fun incompleteState (lastRecord : ObjectNode ): OpaqueStateValue =
346+ override fun incompleteState (lastRecord : SelectQuerier . ResultRow ): OpaqueStateValue =
345347 MsSqlServerJdbcStreamStateValue .snapshotCheckpoint(
346348 primaryKey = checkpointColumns,
347- primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ? : Jsons .nullNode() },
349+ primaryKeyCheckpoint =
350+ checkpointColumns.map { lastRecord.data.toJson()[it.id] ? : Jsons .nullNode() },
348351 )
349352}
350353
351354/* * RFR for CDC. */
352355class MsSqlServerJdbcCdcRfrSnapshotPartition (
353356 selectQueryGenerator : SelectQueryGenerator ,
354357 streamState : DefaultJdbcStreamState ,
355- primaryKey : List <Field >,
358+ primaryKey : List <EmittedField >,
356359 override val lowerBound : List <JsonNode >? ,
357360 override val upperBound : List <JsonNode >? ,
358361) : MsSqlServerJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) {
@@ -367,10 +370,11 @@ class MsSqlServerJdbcCdcRfrSnapshotPartition(
367370 )
368371 }
369372
370- override fun incompleteState (lastRecord : ObjectNode ): OpaqueStateValue =
373+ override fun incompleteState (lastRecord : SelectQuerier . ResultRow ): OpaqueStateValue =
371374 MsSqlServerCdcInitialSnapshotStateValue .snapshotCheckpoint(
372375 primaryKey = checkpointColumns,
373- primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ? : Jsons .nullNode() },
376+ primaryKeyCheckpoint =
377+ checkpointColumns.map { lastRecord.data.toJson()[it.id] ? : Jsons .nullNode() },
374378 )
375379}
376380
@@ -381,25 +385,26 @@ class MsSqlServerJdbcCdcRfrSnapshotPartition(
381385class MsSqlServerJdbcCdcSnapshotPartition (
382386 selectQueryGenerator : SelectQueryGenerator ,
383387 streamState : DefaultJdbcStreamState ,
384- primaryKey : List <Field >,
388+ primaryKey : List <EmittedField >,
385389 override val lowerBound : List <JsonNode >? ,
386390) : MsSqlServerJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) {
387391 override val upperBound: List <JsonNode >? = null
388392 override val completeState: OpaqueStateValue
389393 get() = MsSqlServerCdcInitialSnapshotStateValue .getSnapshotCompletedState(stream)
390394
391- override fun incompleteState (lastRecord : ObjectNode ): OpaqueStateValue =
395+ override fun incompleteState (lastRecord : SelectQuerier . ResultRow ): OpaqueStateValue =
392396 MsSqlServerCdcInitialSnapshotStateValue .snapshotCheckpoint(
393397 primaryKey = checkpointColumns,
394- primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ? : Jsons .nullNode() },
398+ primaryKeyCheckpoint =
399+ checkpointColumns.map { lastRecord.data.toJson()[it.id] ? : Jsons .nullNode() },
395400 )
396401}
397402
398403sealed class MsSqlServerJdbcCursorPartition (
399404 selectQueryGenerator : SelectQueryGenerator ,
400405 streamState : DefaultJdbcStreamState ,
401- checkpointColumns : List <Field >,
402- val cursor : Field ,
406+ checkpointColumns : List <EmittedField >,
407+ val cursor : EmittedField ,
403408 private val explicitCursorUpperBound : JsonNode ? ,
404409 val cursorCutoffTime : JsonNode ? = null ,
405410) :
@@ -433,7 +438,7 @@ sealed class MsSqlServerJdbcCursorPartition(
433438 val querySpec =
434439 SelectQuerySpec (
435440 SelectColumns (stream.fields + checkpointColumns),
436- from ,
441+ FromSample (stream.name, stream.namespace, sampleRateInvPow2, sampleSize, where) ,
437442 NoWhere ,
438443 OrderBy (checkpointColumns),
439444 Limit (sampleSize.toLong())
@@ -454,9 +459,9 @@ sealed class MsSqlServerJdbcCursorPartition(
454459class MsSqlServerJdbcSnapshotWithCursorPartition (
455460 selectQueryGenerator : SelectQueryGenerator ,
456461 streamState : DefaultJdbcStreamState ,
457- primaryKey : List <Field >,
462+ primaryKey : List <EmittedField >,
458463 override val lowerBound : List <JsonNode >? ,
459- cursor : Field ,
464+ cursor : EmittedField ,
460465 cursorUpperBound : JsonNode ? ,
461466 cursorCutoffTime : JsonNode ? = null ,
462467) :
@@ -478,21 +483,22 @@ class MsSqlServerJdbcSnapshotWithCursorPartition(
478483 getEffectiveCursorCheckpoint(cursorCutoffTime, cursorUpperBound, Jsons .nullNode()),
479484 )
480485
481- override fun incompleteState (lastRecord : ObjectNode ): OpaqueStateValue =
486+ override fun incompleteState (lastRecord : SelectQuerier . ResultRow ): OpaqueStateValue =
482487 MsSqlServerJdbcStreamStateValue .snapshotWithCursorCheckpoint(
483488 primaryKey = checkpointColumns,
484- primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ? : Jsons .nullNode() },
489+ primaryKeyCheckpoint =
490+ checkpointColumns.map { lastRecord.data.toJson()[it.id] ? : Jsons .nullNode() },
485491 cursor,
486492 )
487493}
488494
489495class MsSqlServerJdbcSplittableSnapshotWithCursorPartition (
490496 selectQueryGenerator : SelectQueryGenerator ,
491497 streamState : DefaultJdbcStreamState ,
492- primaryKey : List <Field >,
498+ primaryKey : List <EmittedField >,
493499 override val lowerBound : List <JsonNode >? ,
494500 override val upperBound : List <JsonNode >? ,
495- cursor : Field ,
501+ cursor : EmittedField ,
496502 cursorUpperBound : JsonNode ? ,
497503 cursorCutoffTime : JsonNode ? = null ,
498504) :
@@ -524,10 +530,11 @@ class MsSqlServerJdbcSplittableSnapshotWithCursorPartition(
524530 )
525531 }
526532
527- override fun incompleteState (lastRecord : ObjectNode ): OpaqueStateValue =
533+ override fun incompleteState (lastRecord : SelectQuerier . ResultRow ): OpaqueStateValue =
528534 MsSqlServerJdbcStreamStateValue .snapshotWithCursorCheckpoint(
529535 primaryKey = checkpointColumns,
530- primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ? : Jsons .nullNode() },
536+ primaryKeyCheckpoint =
537+ checkpointColumns.map { lastRecord.data.toJson()[it.id] ? : Jsons .nullNode() },
531538 cursor,
532539 )
533540}
@@ -539,7 +546,7 @@ class MsSqlServerJdbcSplittableSnapshotWithCursorPartition(
539546class MsSqlServerJdbcCursorIncrementalPartition (
540547 selectQueryGenerator : SelectQueryGenerator ,
541548 streamState : DefaultJdbcStreamState ,
542- cursor : Field ,
549+ cursor : EmittedField ,
543550 val cursorLowerBound : JsonNode ,
544551 override val isLowerBoundIncluded : Boolean ,
545552 cursorUpperBound : JsonNode ? ,
@@ -564,10 +571,10 @@ class MsSqlServerJdbcCursorIncrementalPartition(
564571 getEffectiveCursorCheckpoint(cursorCutoffTime, cursorUpperBound, cursorLowerBound),
565572 )
566573
567- override fun incompleteState (lastRecord : ObjectNode ): OpaqueStateValue =
574+ override fun incompleteState (lastRecord : SelectQuerier . ResultRow ): OpaqueStateValue =
568575 MsSqlServerJdbcStreamStateValue .cursorIncrementalCheckpoint(
569576 cursor,
570- cursorCheckpoint = lastRecord[cursor.id] ? : Jsons .nullNode(),
577+ cursorCheckpoint = lastRecord.data.toJson() [cursor.id] ? : Jsons .nullNode(),
571578 )
572579}
573580
0 commit comments