Пример #1
0
 public ClickHouseTcpClient(
     TcpClient client,
     ClickHouseBinaryProtocolReader reader,
     ClickHouseBinaryProtocolWriter writer,
     ClickHouseConnectionSettings settings,
     ClickHouseServerInfo serverInfo,
     IClickHouseTypeInfoProvider typeInfoProvider)
 {
     _reader          = reader ?? throw new ArgumentNullException(nameof(reader));
     _writer          = writer ?? throw new ArgumentNullException(nameof(writer));
     _client          = client ?? throw new ArgumentNullException(nameof(client));
     _settings        = settings ?? throw new ArgumentNullException(nameof(settings));
     ServerInfo       = serverInfo;
     TypeInfoProvider = typeInfoProvider;
 }
Пример #2
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (options.Count > 1)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"Too many arguments in the definition of \"{TypeName}\".");
            }

            var elementTypeInfo = typeInfoProvider.GetTypeInfo(options[0]);

            return(new ArrayTypeInfo(elementTypeInfo));
        }
Пример #3
0
 IClickHouseColumnTypeInfo IClickHouseColumnTypeInfo.GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
 {
     throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"The type \"{TypeName}\" does not support arguments.");
 }
Пример #4
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            var  parsedOptions      = new List <KeyValuePair <string, TValue> >(options.Count);
            var  complexNameBuilder = new StringBuilder(TypeName).Append('(');
            bool isFirst            = true;

            foreach (var option in options)
            {
                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    complexNameBuilder.Append(", ");
                }

                var keyStrLen = ClickHouseSyntaxHelper.GetSingleQuoteStringLength(option.Span);
                if (keyStrLen < 0)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The fragment \"{option}\" is not recognized as an item of the enum.");
                }

                var key       = ClickHouseSyntaxHelper.GetSingleQuoteString(option.Slice(0, keyStrLen).Span);
                var valuePart = option.Slice(keyStrLen);
                var eqSignIdx = valuePart.Span.IndexOf('=');
                if (eqSignIdx < 0)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The fragment \"{option}\" is not recognized as an item of the enum.");
                }

                valuePart = valuePart.Slice(eqSignIdx + 1).Trim();
                if (!TryParse(valuePart.Span, out var value))
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The value {valuePart} is not a valid value of {TypeName}.");
                }

                complexNameBuilder.Append(option);
                parsedOptions.Add(new KeyValuePair <string, TValue>(key, value));
            }

            var complexName = complexNameBuilder.Append(')').ToString();

            return(CreateDetailedTypeInfo(complexName, parsedOptions));
        }
Пример #5
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            var  parsedOptions      = new List <KeyValuePair <string, TValue> >(options.Count);
            var  complexNameBuilder = new StringBuilder(TypeName).Append('(');
            bool isFirst            = true;

            foreach (var option in options)
            {
                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    complexNameBuilder.Append(", ");
                }

                var optionStr = option.ToString();
                var match     = _enumItemRegex.Match(optionStr);
                if (!match.Success)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The fragment \"{optionStr}\" is not recognized as an item of the enum.");
                }

                var key      = match.Groups[1].Value;
                var valueStr = match.Groups[2].Value;

                if (!TryParse(valueStr, out var value))
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The value {valueStr} is not a valid value of {TypeName}.");
                }

                complexNameBuilder.Append(optionStr);
                parsedOptions.Add(new KeyValuePair <string, TValue>(key, value));
            }

            var complexName = complexNameBuilder.Append(')').ToString();

            return(CreateDetailedTypeInfo(complexName, parsedOptions));
        }
Пример #6
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (_elementTypes != null)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, "The type is already fully specified.");
            }

            var elementTypes = new List <IClickHouseColumnTypeInfo>(options.Count);

            elementTypes.AddRange(options.Select(typeInfoProvider.GetTypeInfo));

            return(new TupleTypeInfo(elementTypes));
        }
Пример #7
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (options.Count > 2)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"Too many arguments in the definition of \"{TypeName}\".");
            }

            if (!int.TryParse(options[0].Span, NumberStyles.Integer, CultureInfo.InvariantCulture, out var precision))
            {
                throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The first argument (precision) of the type \"{TypeName}\" must be an integer.");
            }
            else if (precision < 0)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The precision value for the type \"{TypeName}\" must be a non-negative number.");
            }

            if (options.Count == 2)
            {
                var tzCode = options[1].Trim('\'').ToString();
                return(new DateTime64TypeInfo(precision, tzCode, true));
            }

            return(new DateTime64TypeInfo(precision, _timeZoneCode, false));
        }
Пример #8
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (_elementTypes != null)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, "The type is already fully specified.");
            }

            var           complexTypeNameBuilder = new StringBuilder(TypeName).Append('(');
            var           elementTypes           = new List <IClickHouseColumnTypeInfo>(options.Count);
            List <string>?elementNames           = null;

            foreach (var option in options)
            {
                if (elementTypes.Count > 0)
                {
                    complexTypeNameBuilder.Append(", ");
                }

                var identifierLen = ClickHouseSyntaxHelper.GetIdentifierLiteralLength(option.Span);
                if (identifierLen == option.Span.Length)
                {
                    identifierLen = -1;
                }

                if (identifierLen < 0)
                {
                    if (elementNames != null)
                    {
                        throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, "A tuple can be either named or not. Mixing of named and unnamed arguments is not allowed.");
                    }

                    var typeInfo = typeInfoProvider.GetTypeInfo(option);
                    elementTypes.Add(typeInfo);
                }
                else
                {
                    if (elementNames == null)
                    {
                        if (elementTypes.Count > 0)
                        {
                            throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, "A tuple can be either named or not. Mixing of named and unnamed arguments is not allowed.");
                        }

                        elementNames = new List <string>(options.Count);
                    }

                    var name     = ClickHouseSyntaxHelper.GetIdentifier(option.Span.Slice(0, identifierLen));
                    var typeInfo = typeInfoProvider.GetTypeInfo(option.Slice(identifierLen + 1));

                    elementTypes.Add(typeInfo);
                    elementNames.Add(name);

                    complexTypeNameBuilder.Append(option.Slice(0, identifierLen)).Append(' ');
                }

                complexTypeNameBuilder.Append(elementTypes[^ 1].ComplexTypeName);
Пример #9
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (_baseType != null)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, "The type is already fully specified.");
            }

            if (options.Count > 1)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"Too many arguments in the definition of \"{TypeName}\".");
            }

            var baseType = typeInfoProvider.GetTypeInfo(options[0]);

            return(new LowCardinalityTypeInfo(baseType));
        }
Пример #10
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (_length != null)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, "The type is already fully specified.");
            }

            if (options.Count > 1)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"Too many arguments in the definition of \"{TypeName}\".");
            }

            if (!int.TryParse(options[0].Span, NumberStyles.Integer, CultureInfo.InvariantCulture, out var length) || length <= 0)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"The length of \"{TypeName}({options[0].ToString()})\" must be a positive number.");
            }

            return(new FixedStringTypeInfo(length));
        }
Пример #11
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            int?precision = null;
            int scale;

            if (options.Count == 1)
            {
                if (!int.TryParse(options[0].Span, NumberStyles.Integer, CultureInfo.InvariantCulture, out scale) || scale < 0)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The scale value for the type \"{TypeName}\" must be a non-negative number.");
                }
            }
            else if (options.Count == 2)
            {
                if (!int.TryParse(options[0].Span, NumberStyles.Integer, CultureInfo.InvariantCulture, out var firstValue) || firstValue <= 0)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The first parameter in options (precision) for the type \"{TypeName}\" must be a positive number.");
                }

                precision = firstValue;

                if (!int.TryParse(options[1].Span, NumberStyles.Integer, CultureInfo.InvariantCulture, out scale) || scale < 0)
                {
                    throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The second parameter in options (scale) for the type \"{TypeName}\" must be a non-negative number.");
                }
            }
            else
            {
                throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"Too many options for the type \"{TypeName}\".");
            }

            if (_precision != null && precision != null)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The value of the precision can not be redefined for the type \"{TypeName}\".");
            }

            var complexTypeName = TypeName + "(" + string.Join(", ", options) + ")";

            return(CloneWithOptions(complexTypeName, precision, scale));
        }
Пример #12
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (options.Count > 1)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, $"Too many arguments in the definition of \"{TypeName}\".");
            }

            var tzCode = options[0].Trim('\'').ToString();

            return(new DateTimeTypeInfo(tzCode, true));
        }
Пример #13
0
        public IClickHouseColumnTypeInfo GetDetailedTypeInfo(List <ReadOnlyMemory <char> > options, IClickHouseTypeInfoProvider typeInfoProvider)
        {
            if (_typeArgs != null)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.TypeNotSupported, "The type is already fully specified.");
            }

            if (options.Count < 2)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"The type \"{TypeName}\" requires two type arguments: key and value.");
            }

            if (options.Count > 2)
            {
                throw new ClickHouseException(ClickHouseErrorCodes.InvalidTypeName, $"Too many options for the type \"{TypeName}\".");
            }

            var keyType   = typeInfoProvider.GetTypeInfo(options[0]);
            var valueType = typeInfoProvider.GetTypeInfo(options[1]);

            var underlyingTypeName = $"Array(Tuple({keyType.ComplexTypeName}, {valueType.ComplexTypeName}))";
            var undelyingType      = typeInfoProvider.GetTypeInfo(underlyingTypeName);

            return(new MapTypeInfo(keyType, valueType, undelyingType));
        }