From: Daniele Varrazzo Date: Mon, 7 Jun 2021 20:44:00 +0000 (+0100) Subject: Pad second fractions to micros using a lookup table X-Git-Tag: 3.0.dev0~39^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=88f0fa634cb65fa0875a39792753ee7bc6353cd2;p=thirdparty%2Fpsycopg.git Pad second fractions to micros using a lookup table --- diff --git a/psycopg3/psycopg3/types/date.py b/psycopg3/psycopg3/types/date.py index 9f71a9181..5c2177206 100644 --- a/psycopg3/psycopg3/types/date.py +++ b/psycopg3/psycopg3/types/date.py @@ -324,10 +324,9 @@ class TimeLoader(Loader): # Pad the fraction of second to get millis if ms: - if len(ms) == 6: - ims = int(ms) - else: - ims = int(ms + _ms_trail[len(ms)]) + ims = int(ms) + if len(ms) < 6: + ims *= _uspad[len(ms)] else: ims = 0 @@ -379,10 +378,9 @@ class TimetzLoader(Loader): # Pad the fraction of second to get millis if ms: - if len(ms) == 6: - ims = int(ms) - else: - ims = int(ms + _ms_trail[len(ms)]) + ims = int(ms) + if len(ms) < 6: + ims *= _uspad[len(ms)] else: ims = 0 @@ -517,10 +515,9 @@ class TimestampLoader(Loader): # Pad the fraction of second to get millis if ms: - if len(ms) == 6: - ims = int(ms) - else: - ims = int(ms + _ms_trail[len(ms)]) + ims = int(ms) + if len(ms) < 6: + ims *= _uspad[len(ms)] else: ims = 0 @@ -589,10 +586,9 @@ class TimestamptzLoader(Loader): # Pad the fraction of second to get millis if ms: - if len(ms) == 6: - ims = int(ms) - else: - ims = int(ms + _ms_trail[len(ms)]) + ims = int(ms) + if len(ms) < 6: + ims *= _uspad[len(ms)] else: ims = 0 @@ -746,4 +742,4 @@ _month_abbr = { } # Pad to get milliseconds from a fraction of seconds -_ms_trail = [b"000000", b"00000", b"0000", b"000", b"00", b"0"] +_uspad = [0, 100_000, 10_000, 1_000, 100, 10, 1] diff --git a/psycopg3_c/psycopg3_c/types/date.pyx b/psycopg3_c/psycopg3_c/types/date.pyx index 9fcb30657..b8af95bbf 100644 --- a/psycopg3_c/psycopg3_c/types/date.pyx +++ b/psycopg3_c/psycopg3_c/types/date.pyx @@ -14,13 +14,17 @@ cdef extern from "Python.h": const char *PyUnicode_AsUTF8AndSize(unicode obj, Py_ssize_t *size) except NULL object PyTimeZone_FromOffset(object offset) -# Hack to compile on Python 3.6 cdef extern from *: """ +/* Hack to compile on Python 3.6 */ #if PY_VERSION_HEX < 0x03070000 #define PyTimeZone_FromOffset(x) x #endif + +/* Multipliers from fraction of seconds to microseconds */ +static int _uspad[] = {0, 100000, 10000, 1000, 100, 10, 1}; """ + cdef int *_uspad from datetime import date, time, timedelta, datetime, timezone @@ -876,7 +880,7 @@ cdef const char *_parse_date_values(const char *ptr, int *vals, int nvals): return ptr -cdef const char *_parse_micros(const char *ptr, int *us): +cdef const char *_parse_micros(const char *start, int *us): """ Parse microseconds from a string. @@ -884,21 +888,18 @@ cdef const char *_parse_micros(const char *ptr, int *us): Return the pointer at the separator after the final digit. """ - cdef int ndigits = 0 + cdef const char *ptr = start while ptr[0]: if b'0' <= ptr[0] <= b'9': us[0] = us[0] * 10 + (ptr[0] - b'0') - ndigits += 1 else: break ptr += 1 # Pad the fraction of second to get millis - if us[0]: - while ndigits < 6: - us[0] *= 10 - ndigits += 1 + if us[0] and ptr - start < 6: + us[0] *= _uspad[ptr - start] return ptr