@@ -29,7 +29,8 @@ struct ExtendedQueryStateMachine {
29
29
case sendParseDescribeBindExecuteSync( PostgresQuery )
30
30
case sendParseDescribeSync( name: String , query: String , bindingDataTypes: [ PostgresDataType ] )
31
31
case sendBindExecuteSync( PSQLExecuteStatement )
32
-
32
+ case sendQuery( String )
33
+
33
34
// --- general actions
34
35
case failQuery( EventLoopPromise < PSQLRowStream > , with: PSQLError )
35
36
case succeedQuery( EventLoopPromise < PSQLRowStream > , with: QueryResult )
@@ -85,6 +86,12 @@ struct ExtendedQueryStateMachine {
85
86
state = . messagesSent( queryContext)
86
87
return . sendParseDescribeSync( name: name, query: query, bindingDataTypes: bindingDataTypes)
87
88
}
89
+
90
+ case . simpleQuery( let query, _) :
91
+ return self . avoidingStateMachineCoW { state -> Action in
92
+ state = . messagesSent( queryContext)
93
+ return . sendQuery( query)
94
+ }
88
95
}
89
96
}
90
97
@@ -105,7 +112,7 @@ struct ExtendedQueryStateMachine {
105
112
106
113
self . isCancelled = true
107
114
switch queryContext. query {
108
- case . unnamed( _, let eventLoopPromise) , . executeStatement( _, let eventLoopPromise) :
115
+ case . unnamed( _, let eventLoopPromise) , . executeStatement( _, let eventLoopPromise) , . simpleQuery ( _ , let eventLoopPromise ) :
109
116
return . failQuery( eventLoopPromise, with: . queryCancelled)
110
117
111
118
case . prepareStatement( _, _, _, let eventLoopPromise) :
@@ -171,11 +178,19 @@ struct ExtendedQueryStateMachine {
171
178
state = . noDataMessageReceived( queryContext)
172
179
return . succeedPreparedStatementCreation( promise, with: nil )
173
180
}
181
+
182
+ case . simpleQuery:
183
+ return self . setAndFireError ( . unexpectedBackendMessage( . noData) )
174
184
}
175
185
}
176
186
177
187
mutating func rowDescriptionReceived( _ rowDescription: RowDescription ) -> Action {
178
- guard case . parameterDescriptionReceived( let queryContext) = self . state else {
188
+ let queryContext : ExtendedQueryContext
189
+ switch self . state {
190
+ case . messagesSent( let extendedQueryContext) ,
191
+ . parameterDescriptionReceived( let extendedQueryContext) :
192
+ queryContext = extendedQueryContext
193
+ default :
179
194
return self . setAndFireError ( . unexpectedBackendMessage( . rowDescription( rowDescription) ) )
180
195
}
181
196
@@ -198,7 +213,7 @@ struct ExtendedQueryStateMachine {
198
213
}
199
214
200
215
switch queryContext. query {
201
- case . unnamed, . executeStatement:
216
+ case . unnamed, . executeStatement, . simpleQuery :
202
217
return . wait
203
218
204
219
case . prepareStatement( _, _, _, let eventLoopPromise) :
@@ -219,6 +234,9 @@ struct ExtendedQueryStateMachine {
219
234
220
235
case . prepareStatement:
221
236
return . evaluateErrorAtConnectionLevel( . unexpectedBackendMessage( . bindComplete) )
237
+
238
+ case . simpleQuery:
239
+ return self . setAndFireError ( . unexpectedBackendMessage( . bindComplete) )
222
240
}
223
241
224
242
case . noDataMessageReceived( let queryContext) :
@@ -258,20 +276,40 @@ struct ExtendedQueryStateMachine {
258
276
return . wait
259
277
}
260
278
279
+ case . rowDescriptionReceived( let queryContext, let columns) :
280
+ switch queryContext. query {
281
+ case . simpleQuery( _, let eventLoopPromise) :
282
+ // When receiving a data row, we must ensure that the data row column count
283
+ // matches the previously received row description column count.
284
+ guard dataRow. columnCount == columns. count else {
285
+ return self . setAndFireError ( . unexpectedBackendMessage( . dataRow( dataRow) ) )
286
+ }
287
+
288
+ return self . avoidingStateMachineCoW { state -> Action in
289
+ var demandStateMachine = RowStreamStateMachine ( )
290
+ demandStateMachine. receivedRow ( dataRow)
291
+ state = . streaming( columns, demandStateMachine)
292
+ let result = QueryResult ( value: . rowDescription( columns) , logger: queryContext. logger)
293
+ return . succeedQuery( eventLoopPromise, with: result)
294
+ }
295
+
296
+ case . unnamed, . executeStatement, . prepareStatement:
297
+ return self . setAndFireError ( . unexpectedBackendMessage( . dataRow( dataRow) ) )
298
+ }
299
+
261
300
case . drain( let columns) :
262
301
guard dataRow. columnCount == columns. count else {
263
302
return self . setAndFireError ( . unexpectedBackendMessage( . dataRow( dataRow) ) )
264
303
}
265
304
// we ignore all rows and wait for readyForQuery
266
305
return . wait
267
-
306
+
268
307
case . initialized,
269
308
. messagesSent,
270
309
. parseCompleteReceived,
271
310
. parameterDescriptionReceived,
272
311
. noDataMessageReceived,
273
312
. emptyQueryResponseReceived,
274
- . rowDescriptionReceived,
275
313
. bindCompleteReceived,
276
314
. commandComplete,
277
315
. error:
@@ -292,10 +330,36 @@ struct ExtendedQueryStateMachine {
292
330
return . succeedQuery( eventLoopPromise, with: result)
293
331
}
294
332
295
- case . prepareStatement:
333
+ case . prepareStatement, . simpleQuery :
296
334
preconditionFailure ( " Invalid state: \( self . state) " )
297
335
}
298
-
336
+
337
+ case . messagesSent( let context) :
338
+ switch context. query {
339
+ case . simpleQuery( _, let eventLoopGroup) :
340
+ return self . avoidingStateMachineCoW { state -> Action in
341
+ state = . commandComplete( commandTag: commandTag)
342
+ let result = QueryResult ( value: . noRows( . tag( commandTag) ) , logger: context. logger)
343
+ return . succeedQuery( eventLoopGroup, with: result)
344
+ }
345
+
346
+ case . unnamed, . executeStatement, . prepareStatement:
347
+ return self . setAndFireError ( . unexpectedBackendMessage( . commandComplete( commandTag) ) )
348
+ }
349
+
350
+ case . rowDescriptionReceived( let context, _) :
351
+ switch context. query {
352
+ case . simpleQuery( _, let eventLoopPromise) :
353
+ return self . avoidingStateMachineCoW { state -> Action in
354
+ state = . commandComplete( commandTag: commandTag)
355
+ let result = QueryResult ( value: . noRows( . tag( commandTag) ) , logger: context. logger)
356
+ return . succeedQuery( eventLoopPromise, with: result)
357
+ }
358
+
359
+ case . unnamed, . executeStatement, . prepareStatement:
360
+ return self . setAndFireError ( . unexpectedBackendMessage( . commandComplete( commandTag) ) )
361
+ }
362
+
299
363
case . streaming( _, var demandStateMachine) :
300
364
return self . avoidingStateMachineCoW { state -> Action in
301
365
state = . commandComplete( commandTag: commandTag)
@@ -306,14 +370,12 @@ struct ExtendedQueryStateMachine {
306
370
precondition ( self . isCancelled)
307
371
self . state = . commandComplete( commandTag: commandTag)
308
372
return . wait
309
-
373
+
310
374
case . initialized,
311
- . messagesSent,
312
375
. parseCompleteReceived,
313
376
. parameterDescriptionReceived,
314
377
. noDataMessageReceived,
315
378
. emptyQueryResponseReceived,
316
- . rowDescriptionReceived,
317
379
. commandComplete,
318
380
. error:
319
381
return self . setAndFireError ( . unexpectedBackendMessage( . commandComplete( commandTag) ) )
@@ -323,20 +385,32 @@ struct ExtendedQueryStateMachine {
323
385
}
324
386
325
387
mutating func emptyQueryResponseReceived( ) -> Action {
326
- guard case . bindCompleteReceived( let queryContext) = self . state else {
327
- return self . setAndFireError ( . unexpectedBackendMessage( . emptyQueryResponse) )
328
- }
388
+ switch self . state {
389
+ case . bindCompleteReceived( let queryContext) :
390
+ switch queryContext. query {
391
+ case . unnamed( _, let eventLoopPromise) ,
392
+ . executeStatement( _, let eventLoopPromise) :
393
+ return self . avoidingStateMachineCoW { state -> Action in
394
+ state = . emptyQueryResponseReceived
395
+ let result = QueryResult ( value: . noRows( . emptyResponse) , logger: queryContext. logger)
396
+ return . succeedQuery( eventLoopPromise, with: result)
397
+ }
329
398
330
- switch queryContext. query {
331
- case . unnamed( _, let eventLoopPromise) ,
332
- . executeStatement( _, let eventLoopPromise) :
333
- return self . avoidingStateMachineCoW { state -> Action in
334
- state = . emptyQueryResponseReceived
335
- let result = QueryResult ( value: . noRows( . emptyResponse) , logger: queryContext. logger)
336
- return . succeedQuery( eventLoopPromise, with: result)
399
+ case . prepareStatement, . simpleQuery:
400
+ return self . setAndFireError ( . unexpectedBackendMessage( . emptyQueryResponse) )
337
401
}
338
-
339
- case . prepareStatement( _, _, _, _) :
402
+ case . messagesSent( let queryContext) :
403
+ switch queryContext. query {
404
+ case . simpleQuery( _, let eventLoopPromise) :
405
+ return self . avoidingStateMachineCoW { state -> Action in
406
+ state = . emptyQueryResponseReceived
407
+ let result = QueryResult ( value: . noRows( . emptyResponse) , logger: queryContext. logger)
408
+ return . succeedQuery( eventLoopPromise, with: result)
409
+ }
410
+ case . unnamed, . executeStatement, . prepareStatement:
411
+ return self . setAndFireError ( . unexpectedBackendMessage( . emptyQueryResponse) )
412
+ }
413
+ default :
340
414
return self . setAndFireError ( . unexpectedBackendMessage( . emptyQueryResponse) )
341
415
}
342
416
}
@@ -497,7 +571,7 @@ struct ExtendedQueryStateMachine {
497
571
return . evaluateErrorAtConnectionLevel( error)
498
572
} else {
499
573
switch context. query {
500
- case . unnamed( _, let eventLoopPromise) , . executeStatement( _, let eventLoopPromise) :
574
+ case . unnamed( _, let eventLoopPromise) , . executeStatement( _, let eventLoopPromise) , . simpleQuery ( _ , let eventLoopPromise ) :
501
575
return . failQuery( eventLoopPromise, with: error)
502
576
case . prepareStatement( _, _, _, let eventLoopPromise) :
503
577
return . failPreparedStatementCreation( eventLoopPromise, with: error)
@@ -536,7 +610,7 @@ struct ExtendedQueryStateMachine {
536
610
switch context. query {
537
611
case . prepareStatement:
538
612
return true
539
- case . unnamed, . executeStatement:
613
+ case . unnamed, . executeStatement, . simpleQuery :
540
614
return false
541
615
}
542
616
0 commit comments