public async Task Query(QueryRequest request, ChannelWriter <Page> channelWriter, ServerCallContext context) { var parameters = ParameterDecoder.DecodeParameters(request.Parameters); QueryResult queryResult; try { queryResult = await _koraliumExecutor.Execute(request.Query, parameters, context.GetHttpContext()); } catch (AuthorizationFailedException authFailed) { throw new RpcException(new Status(StatusCode.Unauthenticated, authFailed.Message)); } var enumerator = queryResult.Result.GetEnumerator(); Page page = new Page() { Metadata = new QueryMetadata() }; foreach (var metadata in queryResult.Metadata) { page.Metadata.CustomMetadata.Add(new KeyValue() { Name = metadata.Key, Value = ScalarEncoder.EncodeScalarResult(metadata.Value) }); } IEncoder[] encoders = new IEncoder[queryResult.Columns.Count]; Func <object, object>[] propertyGetters = new Func <object, object> [encoders.Length]; int indexCounter = 0; for (int i = 0; i < queryResult.Columns.Count; i++) { var column = queryResult.Columns[i]; var columnMetadata = ToMetadata(ref indexCounter, column); encoders[i] = EncoderHelper.GetEncoder(column.Type, columnMetadata, column.Children); propertyGetters[i] = column.GetFunction; page.Metadata.Columns.Add(columnMetadata); } System.Diagnostics.Stopwatch encodeWatch = new System.Diagnostics.Stopwatch(); encodeWatch.Start(); await EncoderHelper.ReadData(_logger, page, encoders, propertyGetters, enumerator, request.MaxBatchSize, channelWriter); encodeWatch.Stop(); _logger.LogTrace($"Encode time: {encodeWatch.ElapsedMilliseconds} ms"); }
public override async Task DoGet(FlightTicket ticket, FlightServerRecordBatchStreamWriter responseStream, ServerCallContext context) { try { int maxBatchSize = DefaultMaxBatchSize; var maxBatchSizeMetadata = context.RequestHeaders.Get("max-batch-size"); if (maxBatchSizeMetadata != null && int.TryParse(maxBatchSizeMetadata.Value, out var parsedMaxBatchSize)) { maxBatchSize = parsedMaxBatchSize; } var queryResult = await _koraliumTransportService.Execute(ticket.Ticket.ToStringUtf8(), new Shared.SqlParameters(), context.GetHttpContext()); //Get the resulting schema var schema = GetSchema(queryResult.Columns); var encoders = queryResult.Columns.Select(x => EncoderHelper.GetEncoder(x)).ToArray(); foreach (var encoder in encoders) { encoder.NewBatch(); } List <object> list = new List <object>(20000); int count = 0; System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); foreach (var obj in queryResult.Result) { count++; for (int i = 0; i < encoders.Length; i++) { encoders[i].Encode(obj); } if (encoders.Select(x => x.Size()).Sum() > maxBatchSize) { await responseStream.WriteAsync(new RecordBatch(schema, encoders.Select(x => x.BuildArray()), count)); foreach (var encoder in encoders) { encoder.NewBatch(); } count = 0; } } stopwatch.Stop(); var batch = new RecordBatch(schema, encoders.Select(x => x.BuildArray()), count); await responseStream.WriteAsync(batch); } catch (SqlErrorException error) { throw new RpcException(new Status(StatusCode.InvalidArgument, error.Message)); } catch (AuthorizationFailedException authFailed) { throw new RpcException(new Status(StatusCode.Unauthenticated, authFailed.Message)); } catch (Exception e) { throw new RpcException(new Status(StatusCode.Internal, "Internal error")); } }