From 02a5f5c635670ee4c8731d54f507f6bb50de512b Mon Sep 17 00:00:00 2001 From: Andrey Oskin Date: Mon, 13 Mar 2023 20:25:03 +0200 Subject: [PATCH] fix: introduce _tryparse (#265) --- src/parsing.jl | 78 +++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/parsing.jl b/src/parsing.jl index 9c4cebda..a159cd3a 100644 --- a/src/parsing.jl +++ b/src/parsing.jl @@ -111,6 +111,39 @@ Base.convert(::Type{String}, pqv::PQValue) = String(pqv) Base.length(pqv::PQValue) = length(string_view(pqv)) Base.lastindex(pqv::PQValue) = lastindex(string_view(pqv)) + +# Julia bug override, see https://github.com/iamed2/LibPQ.jl/issues/265 +# and https://github.com/iamed2/LibPQ.jl/pull/248 for more details +function _tryparse(::Type{T}, str, timeformat) where T + @static if v"1.6.6" <= VERSION < v"1.7.0" || VERSION > v"1.7.2" + return tryparse(T, str, timeformat) + else + try + return tryparse(T, str, timeformat) + catch err + if !(err isa InexactError) + rethrow(err) + end + end + return nothing + end +end + +function _tryparse(::Type{T}, str) where T + @static if v"1.6.6" <= VERSION < v"1.7.0" || VERSION > v"1.7.2" + return tryparse(T, str) + else + try + return tryparse(T, str) + catch err + if !(err isa InexactError) + rethrow(err) + end + end + return nothing + end +end + # Fallback, because Base requires string iteration state to be indices into the string. # In an ideal world, PQValue would be an AbstractString and this particular method would # not be necessary. @@ -259,23 +292,11 @@ function pqparse(::Type{DateTime}, str::AbstractString) parsed = _tryparse_datetime_inf(DateTime, str) isnothing(parsed) || return parsed - # Please, do not remove @static, see https://github.com/iamed2/LibPQ.jl/issues/265 - # for more details - @static if v"1.6.6" <= VERSION < v"1.7.0" || VERSION > v"1.7.2" - parsed = tryparse(DateTime, str, TIMESTAMP_FORMAT) - isnothing(parsed) || return parsed + parsed = _tryparse(DateTime, str, TIMESTAMP_FORMAT) + isnothing(parsed) || return parsed - return parse(DateTime, _trunc_seconds(str), TIMESTAMP_FORMAT) - else - try - return parse(DateTime, str, TIMESTAMP_FORMAT) - catch err - if !(err isa InexactError) - rethrow(err) - end - end - return parse(DateTime, _trunc_seconds(str), TIMESTAMP_FORMAT) - end + # If there's an error we want to see it here + return parse(DateTime, _trunc_seconds(str), TIMESTAMP_FORMAT) end # ISO, YMD @@ -292,10 +313,11 @@ function pqparse(::Type{ZonedDateTime}, str::AbstractString) isnothing(parsed) || return parsed for fmt in TIMESTAMPTZ_FORMATS[1:(end - 1)] - parsed = tryparse(ZonedDateTime, str, fmt) + parsed = _tryparse(ZonedDateTime, str, fmt) isnothing(parsed) || return parsed end + # If there's an error we want to see it here return parse(ZonedDateTime, _trunc_seconds(str), TIMESTAMPTZ_FORMATS[end]) end @@ -307,9 +329,10 @@ function pqparse(::Type{UTCDateTime}, str::AbstractString) # which is the default str = replace(str, "+00" => "") - parsed = tryparse(UTCDateTime, str, TIMESTAMP_FORMAT) + parsed = _tryparse(UTCDateTime, str, TIMESTAMP_FORMAT) isnothing(parsed) || return parsed + # If there's an error we want to see it here return parse(UTCDateTime, _trunc_seconds(str), TIMESTAMP_FORMAT) end @@ -328,20 +351,11 @@ end _DEFAULT_TYPE_MAP[:time] = Time function pqparse(::Type{Time}, str::AbstractString) - @static if v"1.6.6" <= VERSION < v"1.7.0" || VERSION > v"1.7.2" - result = tryparse(Time, str) - # If there's an error we want to see it here - return isnothing(result) ? parse(Time, _trunc_seconds(str)) : result - else - try - return parse(Time, str) - catch err - if !(err isa InexactError) - rethrow(err) - end - end - return parse(Time, _trunc_seconds(str)) - end + parsed = _tryparse(Time, str) + isnothing(parsed) || return parsed + + # If there's an error we want to see it here + return parse(Time, _trunc_seconds(str)) end # InfExtendedTime support for Dates.TimeType