use of io.crate.protocols.postgres.types.PGTypes in project crate by crate.
the class PostgresWireProtocol method handleExecute.
/**
* Execute Message
* Header:
* | 'E' | int32 len
* <p>
* Body:
* | string portalName
* | int32 maxRows (0 = unlimited)
*/
private void handleExecute(ByteBuf buffer, DelayableWriteChannel channel) {
String portalName = readCString(buffer);
int maxRows = buffer.readInt();
String query = session.getQuery(portalName);
if (query.isEmpty()) {
// remove portal so that it doesn't stick around and no attempt to batch it with follow up statement is made
session.close((byte) 'P', portalName);
Messages.sendEmptyQueryResponse(channel);
return;
}
List<? extends DataType> outputTypes = session.getOutputTypes(portalName);
ResultReceiver resultReceiver;
if (outputTypes == null) {
// this is a DML query
maxRows = 0;
resultReceiver = new RowCountReceiver(query, channel.bypassDelay(), getAccessControl.apply(session.sessionContext()));
} else {
// query with resultSet
resultReceiver = new ResultSetReceiver(query, channel.bypassDelay(), session.transactionState(), getAccessControl.apply(session.sessionContext()), Lists2.map(outputTypes, PGTypes::get), session.getResultFormatCodes(portalName));
}
// .execute is going async and may execute the query in another thread-pool.
// The results are later sent to the clients via the `ResultReceiver` created
// above, The `channel.write` calls - which the `ResultReceiver` makes - may
// happen in a thread which is *not* a netty thread.
// If that is the case, netty schedules the writes intead of running them
// immediately. A consequence of that is that *this* thread can continue
// processing other messages from the client, and if this thread then sends messages to the
// client, these are sent immediately, overtaking the result messages of the
// execute that is triggered here.
//
// This would lead to out-of-order messages. For example, we could send a
// `parseComplete` before the `commandComplete` of the previous statement has
// been transmitted.
//
// To ensure clients receive messages in the correct order we delay all writes
// on the channel until the future below is finished.
CompletableFuture<?> execute = session.execute(portalName, maxRows, resultReceiver);
if (execute != null) {
channel.delayWritesUntil(execute);
}
}
Aggregations