internal QueryParameter ToQueryParameter(BigqueryParameterMode parameterMode)
        {
            if (parameterMode == BigqueryParameterMode.Named && string.IsNullOrEmpty(Name))
            {
                throw new InvalidOperationException("Unnamed parameters cannot be used in command using BigqueryParameterMode.Named");
            }
            var value = Value;

            if (Type == null && value == null)
            {
                throw new InvalidOperationException("A null-valued parameter must have an explicitly specified type");
            }
            var type      = Type ?? InferParameterType(value);
            var parameter = new QueryParameter
            {
                Name          = Name,
                ParameterType = new QueryParameterType {
                    Type = EnumMap.ToApiValue(type)
                },
            };

            switch (type)
            {
            case BigqueryParameterType.Array:
                return(PopulateArrayParameter(parameter, value, ArrayType));

            case BigqueryParameterType.Bool:
                return(parameter.PopulateScalar <bool>(value, x => x ? "TRUE" : "FALSE")
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.Bytes:
                return(parameter.PopulateScalar <byte[]>(value, x => Convert.ToBase64String(x))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.Date:
                return(parameter.PopulateScalar <DateTime>(value, x => x.ToString("yyyy-MM-dd", InvariantCulture))
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd", InvariantCulture))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.DateTime:
                return(parameter.PopulateScalar <DateTime>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.Float64:
                return(parameter.PopulateInteger(value)
                       ?? parameter.PopulateFloatingPoint(value)
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.Int64:
                return(parameter.PopulateInteger(value)
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.String:
                return(parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.Struct: throw new NotImplementedException("Struct parameters are not yet implemented");

            case BigqueryParameterType.Time:
                return(parameter.PopulateScalar <TimeSpan>(value, FormatTimeSpan)
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <DateTime>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigqueryParameterType.Timestamp:
                return(parameter.PopulateScalar <DateTime>(value, x =>
                {
                    if (x.Kind != DateTimeKind.Utc)
                    {
                        throw new InvalidOperationException($"A DateTime with a Kind of {x.Kind} cannot be used for a Timestamp parameter");
                    }
                    return x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF");
                })
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFFzzz", InvariantCulture))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            default: throw new InvalidOperationException($"No conversion available for parameter type {type}");
            }
        }
        internal QueryParameter ToQueryParameter()
        {
            var value = Value;

            if (Type == null && value == null)
            {
                throw new InvalidOperationException("A null-valued parameter must have an explicitly specified type");
            }
            var type      = Type ?? InferParameterType(value);
            var parameter = new QueryParameter
            {
                Name          = Name,
                ParameterType = new QueryParameterType {
                    Type = type.ToParameterApiType()
                },
            };

            switch (type)
            {
            case BigQueryDbType.Array:
                return(PopulateArrayParameter(parameter, value, ArrayElementType));

            case BigQueryDbType.Bool:
                return(parameter.PopulateScalar <bool>(value, x => x ? "TRUE" : "FALSE")
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Bytes:
                return(parameter.PopulateScalar <byte[]>(value, x => Convert.ToBase64String(x))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Date:
                return(parameter.PopulateScalar <DateTime>(value, x => x.AsBigQueryDate())
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.AsBigQueryDate())
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.DateTime:
                return(parameter.PopulateScalar <DateTime>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Float64:
                return(parameter.PopulateInteger(value)
                       ?? parameter.PopulateFloatingPoint(value)
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Int64:
                return(parameter.PopulateInteger(value)
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.String:
                return(parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Struct: throw new NotImplementedException("Struct parameters are not yet implemented");

            case BigQueryDbType.Time:
                return(parameter.PopulateScalar <TimeSpan>(value, FormatTimeSpan)
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <DateTime>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Numeric:
                return(parameter.PopulateScalar <BigQueryNumeric>(value, x => x.ToString())
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Geography:
                return(parameter.PopulateScalar <BigQueryGeography>(value, x => x.Text)
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            case BigQueryDbType.Timestamp:
                return(parameter.PopulateScalar <DateTime>(value, x =>
                {
                    if (x.Kind != DateTimeKind.Utc)
                    {
                        throw new InvalidOperationException($"A DateTime with a Kind of {x.Kind} cannot be used for a Timestamp parameter");
                    }
                    return x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF+00", InvariantCulture);
                })
                       ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFFzzz", InvariantCulture))
                       ?? parameter.PopulateScalar <string>(value, x => x)
                       ?? parameter.UseNullScalarOrThrow(value));

            default: throw new InvalidOperationException($"No conversion available for parameter type {type}");
            }
        }