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"));
            }
        }