public SequenceSize ReadNext(ReadOnlySequence <byte> sequence)
            {
                if (_baseReader != null)
                {
                    var result = _baseReader.ReadNext(sequence);
                    return(result);
                }

                var prefixBytesCount = _rowCount - _position;

                if (prefixBytesCount < 0)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.DataReaderError, "Internal error. Attempt to read after the end of the column.");
                }

                if (sequence.Length <= prefixBytesCount)
                {
                    _position += (int)sequence.Length;
                    return(new SequenceSize((int)sequence.Length, 0));
                }
                else
                {
                    _position += prefixBytesCount;
                }

                _baseReader = _underlyingType.CreateSkippingColumnReader(_rowCount);
                var baseSize = _baseReader.ReadNext(sequence.Slice(prefixBytesCount));

                return(new SequenceSize(baseSize.Bytes + prefixBytesCount, baseSize.Elements));
            }
Example #2
0
            public SequenceSize ReadNext(ReadOnlySequence <byte> sequence)
            {
                var slice  = sequence;
                var result = new SequenceSize(0, 0);

                if (_baseReader == null)
                {
                    var header = LowCardinalityColumnReader.TryReadHeader(slice);
                    if (header == null)
                    {
                        return(result);
                    }

                    result = result.AddBytes(header.Value.bytesRead);
                    slice  = slice.Slice(header.Value.bytesRead);

                    _baseRowCount = header.Value.keyCount;
                    _keySize      = header.Value.keySize;

                    _baseReader = _baseType.CreateSkippingColumnReader(_baseRowCount);
                }

                if (_basePosition < _baseRowCount)
                {
                    var baseResult = _baseReader.ReadNext(slice);

                    _basePosition += baseResult.Elements;
                    result         = result.AddBytes(baseResult.Bytes);

                    if (_basePosition < _baseRowCount)
                    {
                        return(result);
                    }
                }

                if (!_headerSkipped)
                {
                    if (sequence.Length - result.Bytes < sizeof(ulong))
                    {
                        return(result);
                    }

                    ulong length = 0;
                    sequence.Slice(result.Bytes, sizeof(ulong)).CopyTo(MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref length, 1)));

                    if ((int)length != _rowCount)
                    {
                        throw new ClickHouseException(ClickHouseErrorCodes.DataReaderError, $"Internal error. Row count check failed: {_rowCount} rows expected, {length} rows detected.");
                    }

                    result         = result.AddBytes(sizeof(ulong));
                    _headerSkipped = true;
                }

                var maxElementsCount = _rowCount - _position;

                if (maxElementsCount <= 0)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.DataReaderError, "Internal error. Attempt to read after the end of the column.");
                }

                var elementCount = (int)Math.Min((sequence.Length - result.Bytes) / _keySize, maxElementsCount);

                _position += elementCount;
                result    += new SequenceSize(elementCount * _keySize, elementCount);

                return(result);
            }