@@ -44,21 +44,61 @@ cdef class CoreProtocol:
44
44
if mtype == b' S' :
45
45
# ParameterStatus
46
46
self ._parse_msg_parameter_status()
47
- continue
47
+
48
48
elif mtype == b' A' :
49
49
# NotificationResponse
50
50
self ._parse_msg_notification()
51
- continue
51
+
52
52
elif mtype == b' N' :
53
53
# 'N' - NoticeResponse
54
54
self ._on_notice(self ._parse_msg_error_response(False ))
55
- continue
56
55
57
- if state == PROTOCOL_AUTH:
56
+ elif mtype == b' E' :
57
+ # ErrorResponse
58
+ self ._parse_msg_error_response(True )
59
+ self ._push_result()
60
+
61
+ elif mtype == b' Z' :
62
+ # ReadyForQuery
63
+ # Auth and SimpleQuery subprotocols use
64
+ # ReadyForQuery as the final result indicator.
65
+ # In client-side exceptional states, ReadyForQuery
66
+ # serves as a synchronization point, indicating
67
+ # when it is safe to push the error into the
68
+ # result waiter.
69
+ self ._parse_msg_ready_for_query()
70
+
71
+ if (state == PROTOCOL_AUTH or
72
+ state == PROTOCOL_CANCELLED or
73
+ state == PROTOCOL_ERROR_CONSUME or
74
+ state == PROTOCOL_SIMPLE_QUERY):
75
+ self ._push_result()
76
+
77
+ elif state == PROTOCOL_BIND_EXECUTE_MANY:
78
+ if self .result_type == RESULT_FAILED:
79
+ self ._push_result()
80
+ else :
81
+ try :
82
+ buf = < WriteBuffer> next(self ._execute_iter)
83
+ except StopIteration :
84
+ self ._push_result()
85
+ except Exception as e:
86
+ self .result_type = RESULT_FAILED
87
+ self .result = e
88
+ self ._push_result()
89
+ else :
90
+ # Next iteration over the executemany()
91
+ # arg sequence.
92
+ self ._send_bind_message(
93
+ self ._execute_portal_name,
94
+ self ._execute_stmt_name,
95
+ buf, 0 )
96
+
97
+ elif state == PROTOCOL_AUTH:
58
98
self ._process__auth(mtype)
59
99
60
- elif state == PROTOCOL_PREPARE :
61
- self ._process__prepare (mtype)
100
+ elif state == PROTOCOL_PARSE_DESCRIBE :
101
+ self ._process__parse_describe (mtype)
62
102
63
103
elif state == PROTOCOL_BIND_EXECUTE:
64
104
self ._process__bind_execute(mtype)
@@ -93,42 +133,26 @@ cdef class CoreProtocol:
93
133
94
134
elif state == PROTOCOL_CANCELLED:
95
135
# discard all messages until the sync message
96
- if mtype == b' E' :
97
- self ._parse_msg_error_response(True )
98
- elif mtype == b' Z' :
99
- self ._parse_msg_ready_for_query()
100
- self ._push_result()
101
- else :
102
- self .buffer.consume_message()
136
+ self .buffer.consume_message()
103
137
104
138
elif state == PROTOCOL_ERROR_CONSUME:
105
139
# Error in protocol (on asyncpg side);
106
140
# discard all messages until sync message
107
-
108
- if mtype == b' Z' :
109
- # Sync point, self to push the result
110
- if self .result_type != RESULT_FAILED:
111
- self .result_type = RESULT_FAILED
112
- self .result = apg_exc.InternalClientError(
113
- ' unknown error in protocol implementation' )
114
-
115
- self ._push_result()
116
-
117
- else :
118
- self .buffer.consume_message()
141
+ self .buffer.consume_message()
119
142
120
143
else :
121
144
raise apg_exc.InternalClientError(
122
145
' protocol is in an unknown state {}' .format(state))
123
146
124
147
except Exception as ex:
148
+ self .state = PROTOCOL_ERROR_CONSUME
125
149
self .result_type = RESULT_FAILED
126
150
self .result = ex
127
151
128
152
if mtype == b' Z' :
153
+ # This should only happen if _parse_msg_ready_for_query()
154
+ # has failed.
129
155
self ._push_result()
130
- else :
131
- self .state = PROTOCOL_ERROR_CONSUME
132
156
133
157
finally :
134
158
if self ._skip_discard:
@@ -153,43 +177,27 @@ cdef class CoreProtocol:
153
177
# BackendKeyData
154
178
self ._parse_msg_backend_key_data()
155
179
156
- elif mtype == b' E' :
157
- # ErrorResponse
158
- self .con_status = CONNECTION_BAD
159
- self ._parse_msg_error_response(True )
160
- self ._push_result()
161
-
162
- elif mtype == b' Z' :
163
- # ReadyForQuery
164
- self ._parse_msg_ready_for_query()
165
- self .con_status = CONNECTION_OK
166
- self ._push_result()
167
-
168
- cdef _process__prepare(self , char mtype):
169
- if mtype == b' t' :
170
- # Parameters description
171
- self .result_param_desc = self .buffer.consume_message().as_bytes()
180
+ # push_result() will be initiated by handling
181
+ # ReadyForQuery or ErrorResponse in the main loop.
172
182
173
- elif mtype == b' 1' :
183
+ cdef _process__parse_describe(self , char mtype):
184
+ if mtype == b' 1' :
174
185
# ParseComplete
175
186
self .buffer.consume_message()
176
187
188
+ elif mtype == b' t' :
189
+ # ParameterDescription
190
+ self .result_param_desc = self .buffer.consume_message().as_bytes()
191
+
177
192
elif mtype == b' T' :
178
- # Row description
193
+ # RowDescription
179
194
self .result_row_desc = self .buffer.consume_message().as_bytes()
180
-
181
- elif mtype == b' E' :
182
- # ErrorResponse
183
- self ._parse_msg_error_response(True )
184
-
185
- elif mtype == b' Z' :
186
- # ReadyForQuery
187
- self ._parse_msg_ready_for_query()
188
195
self ._push_result()
189
196
190
197
elif mtype == b' n' :
191
198
# NoData
192
199
self .buffer.consume_message()
200
+ self ._push_result()
193
201
194
202
cdef _process__bind_execute(self , char mtype):
195
203
if mtype == b' D' :
@@ -199,28 +207,22 @@ cdef class CoreProtocol:
199
207
elif mtype == b' s' :
200
208
# PortalSuspended
201
209
self .buffer.consume_message()
210
+ self ._push_result()
202
211
203
212
elif mtype == b' C' :
204
213
# CommandComplete
205
214
self .result_execute_completed = True
206
215
self ._parse_msg_command_complete()
207
-
208
- elif mtype == b' E' :
209
- # ErrorResponse
210
- self ._parse_msg_error_response(True )
216
+ self ._push_result()
211
217
212
218
elif mtype == b' 2' :
213
219
# BindComplete
214
220
self .buffer.consume_message()
215
221
216
- elif mtype == b' Z' :
217
- # ReadyForQuery
218
- self ._parse_msg_ready_for_query()
219
- self ._push_result()
220
-
221
222
elif mtype == b' I' :
222
223
# EmptyQueryResponse
223
224
self .buffer.consume_message()
225
+ self ._push_result()
224
226
225
227
cdef _process__bind_execute_many(self , char mtype):
226
228
cdef WriteBuffer buf
@@ -237,64 +239,24 @@ cdef class CoreProtocol:
237
239
# CommandComplete
238
240
self ._parse_msg_command_complete()
239
241
240
- elif mtype == b' E' :
241
- # ErrorResponse
242
- self ._parse_msg_error_response(True )
243
-
244
242
elif mtype == b' 2' :
245
243
# BindComplete
246
244
self .buffer.consume_message()
247
245
248
- elif mtype == b' Z' :
249
- # ReadyForQuery
250
- self ._parse_msg_ready_for_query()
251
- if self .result_type == RESULT_FAILED:
252
- self ._push_result()
253
- else :
254
- try :
255
- buf = < WriteBuffer> next(self ._execute_iter)
256
- except StopIteration :
257
- self ._push_result()
258
- except Exception as e:
259
- self .result_type = RESULT_FAILED
260
- self .result = e
261
- self ._push_result()
262
- else :
263
- # Next iteration over the executemany() arg sequence
264
- self ._send_bind_message(
265
- self ._execute_portal_name, self ._execute_stmt_name,
266
- buf, 0 )
267
-
268
246
elif mtype == b' I' :
269
247
# EmptyQueryResponse
270
248
self .buffer.consume_message()
271
249
272
250
cdef _process__bind(self , char mtype):
273
- if mtype == b' E' :
274
- # ErrorResponse
275
- self ._parse_msg_error_response(True )
276
-
277
- elif mtype == b' 2' :
251
+ if mtype == b' 2' :
278
252
# BindComplete
279
253
self .buffer.consume_message()
280
-
281
- elif mtype == b' Z' :
282
- # ReadyForQuery
283
- self ._parse_msg_ready_for_query()
284
254
self ._push_result()
285
255
286
256
cdef _process__close_stmt_portal(self , char mtype):
287
- if mtype == b' E' :
288
- # ErrorResponse
289
- self ._parse_msg_error_response(True )
290
-
291
- elif mtype == b' 3' :
257
+ if mtype == b' 3' :
292
258
# CloseComplete
293
259
self .buffer.consume_message()
294
-
295
- elif mtype == b' Z' :
296
- # ReadyForQuery
297
- self ._parse_msg_ready_for_query()
298
260
self ._push_result()
299
261
300
262
cdef _process__simple_query(self , char mtype):
@@ -304,42 +266,21 @@ cdef class CoreProtocol:
304
266
# 'T' - RowDescription
305
267
self .buffer.consume_message()
306
268
307
- elif mtype == b' E' :
308
- # ErrorResponse
309
- self ._parse_msg_error_response(True )
310
-
311
- elif mtype == b' Z' :
312
- # ReadyForQuery
313
- self ._parse_msg_ready_for_query()
314
- self ._push_result()
315
-
316
269
elif mtype == b' C' :
317
270
# CommandComplete
318
271
self ._parse_msg_command_complete()
319
-
320
272
else :
321
273
# We don't really care about COPY IN etc
322
274
self .buffer.consume_message()
323
275
324
276
cdef _process__copy_out(self , char mtype):
325
- if mtype == b' E' :
326
- self ._parse_msg_error_response(True )
327
-
328
- elif mtype == b' H' :
277
+ if mtype == b' H' :
329
278
# CopyOutResponse
330
279
self ._set_state(PROTOCOL_COPY_OUT_DATA)
331
280
self .buffer.consume_message()
332
281
333
- elif mtype == b' Z' :
334
- # ReadyForQuery
335
- self ._parse_msg_ready_for_query()
336
- self ._push_result()
337
-
338
282
cdef _process__copy_out_data(self , char mtype):
339
- if mtype == b' E' :
340
- self ._parse_msg_error_response(True )
341
-
342
- elif mtype == b' d' :
283
+ if mtype == b' d' :
343
284
# CopyData
344
285
self ._parse_copy_data_msgs()
345
286
@@ -351,37 +292,18 @@ cdef class CoreProtocol:
351
292
elif mtype == b' C' :
352
293
# CommandComplete
353
294
self ._parse_msg_command_complete()
354
-
355
- elif mtype == b' Z' :
356
- # ReadyForQuery
357
- self ._parse_msg_ready_for_query()
358
295
self ._push_result()
359
296
360
297
cdef _process__copy_in(self , char mtype):
361
- if mtype == b' E' :
362
- self ._parse_msg_error_response(True )
363
-
364
- elif mtype == b' G' :
298
+ if mtype == b' G' :
365
299
# CopyInResponse
366
300
self ._set_state(PROTOCOL_COPY_IN_DATA)
367
301
self .buffer.consume_message()
368
302
369
- elif mtype == b' Z' :
370
- # ReadyForQuery
371
- self ._parse_msg_ready_for_query()
372
- self ._push_result()
373
-
374
303
cdef _process__copy_in_data(self , char mtype):
375
- if mtype == b' E' :
376
- self ._parse_msg_error_response(True )
377
-
378
- elif mtype == b' C' :
304
+ if mtype == b' C' :
379
305
# CommandComplete
380
306
self ._parse_msg_command_complete()
381
-
382
- elif mtype == b' Z' :
383
- # ReadyForQuery
384
- self ._parse_msg_ready_for_query()
385
307
self ._push_result()
386
308
387
309
cdef _parse_msg_command_complete(self ):
@@ -739,7 +661,7 @@ cdef class CoreProtocol:
739
661
WriteBuffer buf
740
662
741
663
self ._ensure_connected()
742
- self ._set_state(PROTOCOL_PREPARE )
664
+ self ._set_state(PROTOCOL_PARSE_DESCRIBE )
743
665
744
666
buf = WriteBuffer.new_message(b' P' )
745
667
buf.write_str(stmt_name, self .encoding)
0 commit comments